SpringBoot | AOP切面日志记录
SysLog 注解
import java.lang.annotation.*;
@Target(ElementType.METHOD) //该注解应用于方法
@Retention(RetentionPolicy.RUNTIME) //在vm运行期间保留注解
@Documented //将注解包含在javadoc中
public @interface SysLog {
String value() default ""; // 接口名称
boolean check() default true; //是否校验token
}
切面处理类
/**
* 系统日志,切面处理类
* 处理@SysLog注解
*/
@Aspect
@Component
public class SysLogAspect {
private static Logger logger = LoggerFactory.getLogger(SysLogAspect.class);
@Autowired
private SysLogMapper sysLogMapper;
/**
* SpringBoot获取当前环境代码,Spring获取当前环境代码
*/
@Value("${spring.profiles.active}")
private String profiles;
@Pointcut("@annotation(com.zhang.oneday.common.annotation.SysLog)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long beginTime = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLogEntity sysLog = new SysLogEntity();
SysLog syslog = method.getAnnotation(SysLog.class);
if (syslog != null) {
//注解上的描述
String value = syslog.value();
logger.info("=====> {}", value);
sysLog.setOperation(value);
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
sysLog.setIp(IPUtils.getIp(request));
sysLog.setCreateDate(new Date());
sysLog.setProfiles(profiles);
//请求的参数
Object[] args = joinPoint.getArgs();
JSONObject paramObj = new JSONObject();
Map<String, String[]> paramMap = request.getParameterMap();
for (String key : paramMap.keySet()) {
String[] values = paramMap.get(key);
for (int i = 0; i < values.length; i++) {
String value = values[i];
paramObj.put(key, value);
}
}
String params = paramObj.isEmpty() ? "" : JSONObject.toJSONString(paramObj);
sysLog.setParams(params);
logger.info("==> 参数:{}", params);
// token验证(拦截器执行顺序优先于aop,如果token验证使用拦截器实现抛出异常后无法记录日志)
if (syslog.check()) {
String token = request.getHeader("token");
if (StringUtils.isBlank(token)) {
// 异常记录并抛出
sysLog.setResult(JSON.toJSONString(R.error(ResponseCode.TOKEN_EMPTY)));
sysLogMapper.insertSysLog(sysLog);
throw new ServiceException(ResponseCode.TOKEN_EMPTY);
}
try {
Claims jws = TokenUtil.parse("wxToken", token);
Long userId = Long.valueOf(jws.get("userId").toString());
request.setAttribute("userId", userId);
sysLog.setUserId(userId);
} catch (Exception e) {
sysLog.setResult(JSON.toJSONString(R.error(ResponseCode.TOKEN_AUTHENTICATION_FAILED)));
sysLogMapper.insertSysLog(sysLog);
throw new ServiceException(ResponseCode.TOKEN_AUTHENTICATION_FAILED);
}
}
// 返回内容
Object result = joinPoint.proceed(args);
String results = JSONObject.toJSONString(result);
sysLog.setResult(results.replaceAll("\\s*|\t|\r|\n", ""));
logger.info("==> 返回:{}", results);
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
sysLog.setTime(time);
//保存系统日志
sysLogMapper.insertSysLog(sysLog);
return result;
}
}
日志实体类
@Data
public class SysLogEntity implements Serializable {
private Long id;
private Long userId;
private String operation; //操作
private String method; //方法名
private String params; //参数
private String result; //参数
private String ip; //ip地址
private Date createDate; //操作时间
private long time; //请求时间
private String profiles; //当前环境
}