原因
这两天在看合作伙伴公司近期写的代码,发现合作伙伴为了验证每个方法的调用时机与监控其性能,在每个方法里用日志输出入口与出口的时间并监控方法的其入参与出参,整个工程包15%的代码是重复的。
而且还在用此办法写新的项目,于是我考虑利用切面知识将方法的性能监控抽离出来,形成统一的监控类,将此类放入新工程中,在指定范围的方法被调用时会自动触发此工具,这样在一定程度上提高开发效率。
代码如下:
/**
* @Author [email protected]
* @Description : 日志类工具
* @Date 23:55 2019/4/1
* @return
**/
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 拦截 public protect和private web包里的所有类的所有方法
private final String POINT_CUT = "execution(* com.cmcc.controller.*.*(..))";
private static final String START_TIME = "requestStartTime";
@Pointcut(POINT_CUT)
public void moniLog(){}
@Before("moniLog()")
public void doBefore(JoinPoint joinPoint){
//获取连接点的方法签名对象
Signature signature = joinPoint.getSignature();
logger.info(signature.toLongString());
//获取方法名
String MethodName = signature.getName();
//attributes可以获取request信息 session信息等
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logger.info("访问者IP:"+request.getRemoteAddr());
String url = request.getRequestURL().toString();
logger.info("访问URL:"+url);
//GET OR POST
logger.info(request.getMethod());
// 计算被请求方法消耗时间
Map parameterMap = request.getParameterMap();
logger.info("request start. url:{}, method:{},params:{}", request.getRequestURL().toString(), signature.toString()+"入口" , JsonMapper.obj2String(parameterMap));
long start = System.currentTimeMillis();
request.setAttribute(MethodName+START_TIME, start);
}
@After("moniLog()")
public void doAfter(JoinPoint joinPoint){
//获取方法名
String MethodName = joinPoint.getSignature().getName();
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String url = request.getRequestURL().toString();
long start = (Long) request.getAttribute(MethodName+START_TIME);
long end = System.currentTimeMillis();
logger.info("request completed. url:{}, method:{}, 花费时间:{}ms", url, joinPoint.getSignature().toString()+"出口", end - start);
}
@AfterReturning(returning = "result", pointcut = "moniLog()")
public void doAfterReturn(Object result){
logger.info("请求返回结果: {}", result);
}
}