AOP日志收集
本方法使用threadlocal管理切面前后数据,kafka发送切面数据
@Aspect
@Component
@Order(2)
public class AopLogAspect {
private final static Logger log = LoggerFactory.getLogger(AopLogAspect.class);
@Resource
private IdGeneratorUtil idGeneratorUtil;
private ThreadLocal<JSONObject> logObject = new ThreadLocal<>();
@Value("${topic.log.name}")
private String logTopic;
@Pointcut(value = "@annotation(com.XXX.XXX.log.annotation.OperationLog)")
private void serviceAspect() {
}
@Before(value = "serviceAspect()")
public void methodBefore(JoinPoint joinPoint) {
try {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
assert requestAttributes != null;
HttpServletRequest request = requestAttributes.getRequest();
String ip = IpAddressUtil.getIpAddress(request);
JSONObject jsonObject = new JSONObject();
jsonObject.put("request_id", idGeneratorUtil.snowflakeId());
jsonObject.put("request_time", DateUtil.now());
jsonObject.put("request_ip_port", ip);
jsonObject.put("request_url", request.getRequestURL().toString());
jsonObject.put("request_method", request.getMethod());
String args = Arrays.toString(joinPoint.getArgs());
jsonObject.put("request_args", args);
String requestModule = "未知";
String requestDesc = "未知";
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
OperationLog annotation = method.getAnnotation(OperationLog.class);
LogSystemType systemType = LogSystemType.UNKNOWN;
if (annotation != null) {
systemType = annotation.system();
requestModule = systemType.getDesc() + annotation.module();
requestDesc = annotation.desc();
}
//用户信息的获取,为特定业务,不做展示
HashMap<String, String> userInfo = getUserInfo(request, systemType);
jsonObject.put("request_user_name", userInfo.get("requestUsername"));
jsonObject.put("request_name", userInfo.get("requestName"));
jsonObject.put("request_org", userInfo.get("requestOrg"));
jsonObject.put("request_module", requestModule);
jsonObject.put("request_desc", requestDesc);
logObject.set(jsonObject);
} catch (Exception e) {
logObject.remove();
}
}
/*在业务中穿插的代码做切面处理,DetailParamFormatService需要交给spring管理,代码中执行了DetailParamFormatService.format方法就会进入此方法*/
@AfterReturning(pointcut = "execution(* com.XXX.XXX.log.method.DetailParamFormatService.format(..))&&args(obj, operationType)", returning = "resultValue")
public void serviceDetailParamReturning(Object obj, OperationType operationType, String resultValue) {
JSONObject jsonObject = logObject.get();
jsonObject.put("request_desc", resultValue);
logObject.set(jsonObject);
}
@AfterReturning(returning = "o", pointcut = "serviceAspect()")
public void methodAfterReturing(Object o) {
try {
JSONObject jsonObject = logObject.get();
jsonObject.put("response_time", DateUtil.now());
String jsonString = JSONObject.toJSONString(o);
boolean status = (boolean) JSONObject.parseObject(jsonString).get("success");
if (status) {
jsonObject.put("response_status", ResponseLogStatus.SUCCESS.getDesc());
} else {
jsonObject.put("response_status", ResponseLogStatus.ERROR.getDesc());
}
jsonObject.put("response_content", jsonString);
MqSend.sendMsg(logTopic, JSONObject.toJSONString(logObject.get()));
} finally {
logObject.remove();
}
}
@AfterThrowing(pointcut = "serviceAspect()", throwing = "e")
public void saveExceptionLog(Throwable e) {
try {
JSONObject jsonObject = logObject.get();
if (jsonObject == null) {
return;
}
jsonObject.put("response_time", DateUtil.now());
jsonObject.put("response_status", ResponseLogStatus.ERROR.getDesc());
JSONObject exceptionObject = new JSONObject();
exceptionObject.put("response_exception_name", e.getClass().getName());
exceptionObject.put("response_exception_msg", stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
jsonObject.put("response_content", JSONObject.toJSONString(exceptionObject));
MqSend.sendMsg(logTopic, JSONObject.toJSONString(logObject.get()));
} finally {
logObject.remove();
}
}
/**
* 转换异常信息为字符串
*
* @param exceptionName 异常名称
* @param exceptionMessage 异常信息
* @param elements 堆栈信息
*/
public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
StringBuilder buffer = new StringBuilder();
for (StackTraceElement stet : elements) {
buffer.append(stet).append("\n");
}
return exceptionName + ":" + exceptionMessage + "\n\t" + buffer.toString();
}
}
操作注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationLog {
LogSystemType system();
String module();
String desc();
}
LogSystemType枚举
@Getter
public enum LogSystemType {
/**
*
*/
APP("APP-"),
PC("平台-"),
UNKNOWN("未知-");
private String desc;
LogSystemType(String desc) {
this.desc = desc;
}
}
方法上添加注解
@Resourse
private DetailParamFormatService detailParamFormatService;
@OperationLog(system = LogSystemType.APP, module = "模块名", desc = "执行XXX命令")
public ResponseInfo method(@RequestBody Dto dtoj){
/穿插DetailParamFormatService.format方法
detailParamFormatService.format();
return "666";
}