本文是基于AspectJ静态代理模式 1.maven添加依赖jar包
org.aspectj
aspectjweaver
1.8.13
2.定义log注解类
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoggerManage {/**
* 说明
* @return
*/
public String description();
}
3.创建日志切面类
@Aspect
@Component
public class LoggerAdvice {private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 在这里定义切面的点,Pointcut的表达式语法需要匹配到你调用的方法中
*/
@Pointcut("within(cn.hlvan.citywide.controller..*)")
public void declareJoinPointExpression() {
}@Before("declareJoinPointExpression()")
public void addBeforeLogger(JoinPoint joinPoint) {
try {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
String url = request.getRequestURL().toString();
String method = request.getMethod();
String uri = request.getRequestURI();
String userAgent = request.getHeader("User-Agent");
Cookie cookie = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if (c.getName().endsWith("Token")) {
cookie = c;
break;
}
}
}
String CookieString=cookie==null?"":GsonUtils.getInstance().toJson(cookie);
String params = GsonUtils.toJson(request.getParameterMap());
String apiName = "";
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
for (Method m : methods) {
if (m.getName().equals(methodName)) {
Class[] clazzs = m.getParameterTypes();
if (clazzs.length == arguments.length) {
if (m.getDeclaredAnnotation(LoggerManage.class) != null) {
apiName = m.getDeclaredAnnotation(LoggerManage.class).description();
break;
}
}
}
}
logger.info("apiName:{}, url: {},uri: {}, method: {}, params: {},Cookie:{},UserAgent:{}",
apiName,url,uri, method, params, CookieString,userAgent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}//@AfterReturning(value = "https://www.it610.com/article/declareJoinPointExpression()", returning = "returnObj")
//public void addAfterReturningLogger(JoinPoint joinPoint, Object returnObj) {
//System.out.println("结束");
//}//@AfterThrowing(pointcut = "declareJoinPointExpression()", throwing = "ex")
//public void addAfterThrowingLogger(JoinPoint joinPoint, Exception ex) {
//System.out.println("异常");
//}
@Around(value = "https://www.it610.com/article/declareJoinPointExpression()")
public Object doAround(ProceedingJoinPoint proceeding) throws Throwable {
long beforeTime=System.currentTimeMillis();
//执行被拦截的方法 result是返回结果
Object result = proceeding.proceed();
//debug模式下才计算方法耗时
if (logger.isDebugEnabled()) {
long afterTime=System.currentTimeMillis();
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
logger.info("请求:{} , 耗时:{}ms",request.getRequestURI(),afterTime-beforeTime);
}
//此处可以在log输出result,依据业务要求处理
return result;
}
}
4.在Controller中注解的使用
@LoggerManage(description = "app检查升级")
@GetMapping("/check_update")
public String checkUpdate() {
return "ok";
}
5.调用后的打印信息
apiName:app检查升级, url: http://localhost:8888/check_update , uri: /check_update, method: GET, params: {},Cookie:{"name":"xxxx","value":"XXXX","version":0,"maxAge":-1,"secure":false,"httpOnly":false},UserAgent:XXXX
...
...
...
请求:/driver/check_update , 耗时:953ms
6.其他说明(可以忽略) 如果使用springboot 1.在maven中添加
【Java基础|spring/spring boot 自定义日志注解输出请求参数和结果】
推荐阅读
- 多线程与高并发|4.如何终止线程
- #|15-Spring架构源码分析-Spring代理与AOP
- #|16-Spring AOP源码分析-@EnableAspectJAutoProxy和AspectJAutoProxyRegistrar
- 微软|突发!马斯克 440 亿拿下Twitter!
- 阿里一面(Spring Bean 默认是单例的,高并发情况下,如何保证并发安全())
- 用了这跨操作系统远控软件,我再也不出差了
- 编程语言|疫情下的就业市场,每一位前端工程师,都在勇闯天涯!
- java|编写最新MyBatis核心配置文件
- java|spirngboot2.3.5在controller上加requestMapping导致静态资源前面多加了一层url解决办法