controller方法入参出参加日志打印V2
package com.media.web.aop;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.google.common.base.Throwables;
import com.immotors.zeus.core.exception.ServiceException;
import com.immotors.zeus.core.util.JsonUtil;
import com.media.common.enums.HttpMsg;
import com.media.web.common.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Aspect
@Component
public class ControllerLogAspect {
// 切点表达式需要关注包级关系,否则可能导致日志不生效
@Pointcut("execution(* com.test.web.controller.*.*(..))" +
"&& !execution(* com.test.web.controller.HealthController.*(..))")
public void log() {
// do nothing
}
/**
* 【切点】循环
*
* @param joinPoint 连接点
* @return 返回体
* @throws Throwable 异常
*/
@Around("log()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Class withinType = joinPoint.getSourceLocation().getWithinType();
Logger log = LoggerFactory.getLogger(withinType);
TimeInterval timer = DateUtil.timer();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
CommonResult result = new CommonResult();
result.setCode(String.valueOf(HttpMsg.ERROR.getCode()));
result.setStatus(HttpMsg.ERROR.getCode());
result.setMessage(HttpMsg.SYSTEM_ERROR.getMessage());
result.setSuccess(Boolean.FALSE);
return result;
}
Object objectClass = joinPoint.getTarget();
HttpServletRequest request = requestAttributes.getRequest();
Object[] args = joinPoint.getArgs();
Object[] arguments = new Object[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile) {
continue;
}
arguments[i] = args[i];
}
//创建headers
Map<String, String> headers = new HashMap<>();
Collections.list(request.getHeaderNames()).stream().forEach(str -> headers.put(str, request.getHeader(str)));
Object proceed = null;
try {
proceed = joinPoint.proceed();
} catch (ServiceException e) {
String info = String.format("imzc-service====class:%s====url:%s=====header:%s=====param:%s====用时:%sms",
objectClass, request.getRequestURL().toString(), JsonUtil.toJson(headers), JsonUtil.toJson(arguments), timer.interval());
log.info(info + "====异常堆栈信息:{}", Throwables.getStackTraceAsString(e));
throw e;
} catch (Exception e) {
String info = String.format("imzc-service====class:%s====url:%s=====header:%s=====param:%s====用时:%sms",
objectClass, request.getRequestURL().toString(), JsonUtil.toJson(headers), JsonUtil.toJson(arguments), timer.interval());
log.error(info + "====异常堆栈信息:{}", Throwables.getStackTraceAsString(e));
throw e;
}
log.info("imzc-service====class:" + objectClass + "====url:{}=====header:{}=====param:{}====response :{}====用时:{}ms",
request.getRequestURL().toString().replaceAll("[\r\n]", ""),
JsonUtil.toJson(headers).replaceAll("[\r\n]", ""),
JsonUtil.toJson(arguments).replaceAll("[\r\n]", ""),
JsonUtil.toJson(proceed), timer.interval());
return proceed;
}
}
不积跬步,无以至千里;不积小流,无以成江海。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具