From 126211d28a1cd3ccc58e7f5dcc56b4a0782d8a3b Mon Sep 17 00:00:00 2001 From: haozq <1611483981@qq.com> Date: Tue, 10 Dec 2024 16:54:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=B3=A8=E8=A7=A3=E4=BF=AE?= =?UTF-8?q?=E6=94=B92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/log/aspect/OperLogAspect.java | 255 ++++++++++++++++++ .../common/log/enums/OperaType.java | 55 ++++ 2 files changed, 310 insertions(+) create mode 100644 securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/aspect/OperLogAspect.java create mode 100644 securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/enums/OperaType.java diff --git a/securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/aspect/OperLogAspect.java b/securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/aspect/OperLogAspect.java new file mode 100644 index 0000000..c41c42c --- /dev/null +++ b/securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/aspect/OperLogAspect.java @@ -0,0 +1,255 @@ +package com.securityControl.common.log.aspect; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.securityControl.common.core.utils.aes.DateTimeHelper; +import com.securityControl.common.core.utils.ip.IpUtils; +import com.securityControl.common.log.annotation.SysLog; +import com.securityControl.common.log.enums.BusinessStatus; +import com.securityControl.common.log.service.AsyncLogService; +import com.securityControl.common.security.utils.SecurityUtils; +import com.securityControl.system.api.domain.SysLogsInfo; +import com.securityControl.system.api.domain.SysUser; +import com.securityControl.system.api.model.LoginUser; +import com.securityControl.common.core.utils.ServletUtils; +import com.securityControl.common.core.utils.aes.StringHelper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + + +/** + * @author:cwchen + * @date:2024-02-28-16:47 + * @version:1.0 + * @description:日志切面 + */ +@Aspect +@Component +@Slf4j +public class OperLogAspect { + + + public static String SUCCESS_CODE="200"; + + ThreadLocal currentTime = new ThreadLocal<>(); + + @Autowired + private AsyncLogService asyncLogService; + + + + /** + * 设置操作日志切入点 记录操作日志 在注解的位置切入代码 + */ + @Pointcut("@annotation(com.securityControl.common.log.annotation.SysLog)") + public void operLogPointCut() { + } + + /** + * 设置操作异常切入点记录异常日志 扫描所有controller包下操作 + */ + @Pointcut("execution( * com.securityControl..*.controller..*(..))") + public void operExceptionLogPointCut() { + } + + @Around("operLogPointCut()") + public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { + Object result; + currentTime.set(System.currentTimeMillis()); + //正常处理开始 + result = joinPoint.proceed(); + //正常处理结束 + Long time = System.currentTimeMillis() - currentTime.get(); + currentTime.remove(); + handleLog(joinPoint, null, result, time); + return result; + } + + + @AfterThrowing(pointcut = "operExceptionLogPointCut()", throwing = "e") + public void logAfterThrowing(JoinPoint joinPoint, Exception e) { + // handleLog(joinPoint, e, null, null); + } + + protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult, Long time) { + try { + SysLogsInfo sysLog=new SysLogsInfo(); + // 获取RequestAttributes + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + // 从获取RequestAttributes中获取HttpServletRequest的信息 + HttpServletRequest request = (HttpServletRequest) requestAttributes + .resolveReference(RequestAttributes.REFERENCE_REQUEST); + String methodType=request.getMethod(); + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + //获取注解 + SysLog aopLog = method.getAnnotation(SysLog.class); + + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (null != loginUser && null != loginUser.getSysUser()) { + SysUser sysUser = loginUser.getSysUser(); + sysLog.setUserId(sysUser.getUserId()); + sysLog.setUserName(sysUser.getNickName()); + } + //操作结果 成功/失败 + sysLog.setOperResult(BusinessStatus.SUCCESS.ordinal()+""); + sysLog.setTimes(time != null ? time + "" : null); + // 请求的地址 + String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + sysLog.setOperIp(ip); + + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + //设置请求方法名 + sysLog.setOperMeth(className + "." + methodName + "()"); + // 处理设置注解上的参数 + getControllerMethodDescription(joinPoint, aopLog, sysLog); + + //利用是否有异常定性记录失败信息 + String result = JSON.toJSONString(jsonResult); + JSONObject jsonObject = JSON.parseObject(result); + if (e != null) { + sysLog.setOperResult("0"); + sysLog.setEventType("异常事件"); + sysLog.setErrReason(StringUtils.substring(e.getMessage(), 0, 2000)); + } else{ + if(jsonObject!=null){ + String code=jsonObject.getString("code"); + String msg=jsonObject.getString("msg"); + if(StringHelper.isNotEmpty(code)){ + if(SUCCESS_CODE.equals(code) ){ + sysLog.setOperResult("1"); + sysLog.setEventType("正常事件"); + }else { + sysLog.setOperResult("0"); + sysLog.setEventType("异常事件"); + } + if(StringHelper.isEmpty(msg) || msg.contains("成功") || msg.contains("SUCCESS")){ + sysLog.setErrReason("操作成功"); + }else{ + sysLog.setErrReason(msg); + } + } + }else { + sysLog.setOperResult("1"); + sysLog.setEventType("正常事件"); + sysLog.setErrReason("操作成功"); + } + } + asyncLogService.addSaveSysLog(sysLog); + } catch (Exception exp) { + // 记录本地异常日志 + log.error("==前置通知异常=="); + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param sysLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, SysLog log, SysLogsInfo sysLog) throws Exception { + if (log != null) { + sysLog.setTitle(log.title()); + sysLog.setOperModel(log.model()); + sysLog.setOperType(log.operaType()); + sysLog.setLogType(log.logType()); + sysLog.setOperDetails(log.details()); + sysLog.setOperTime(DateTimeHelper.getNowTime()); + + } else { + //用于无注解的控制层方法 异常抛出 记录 + sysLog.setOperModel("未知模块"); + sysLog.setOperType("未知操作类型"); + sysLog.setOperDetails("未知操作详情"); + sysLog.setOperTime(DateTimeHelper.getNowTime()); + sysLog.setLogType(1); + } + if(log==null){ + return ; + } + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, sysLog); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param sysLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysLogsInfo sysLog) throws Exception { + String params = argsArrayToString(joinPoint.getArgs()); + //避免过长的无用信息 + sysLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray) { + StringBuilder params = new StringBuilder(); + if (paramsArray != null && paramsArray.length > 0) { + for (int i = 0; i < paramsArray.length; i++) { + //排除不需要记录的参数 + if (!isFilterObject(paramsArray[i])) { + Object value = paramsArray[i]; + if (value instanceof MultipartFile) { + MultipartFile file = (MultipartFile) value; + Object jsonObj = JSON.toJSON(file.getOriginalFilename()); + params.append(jsonObj.toString()).append(" "); + } else if (value instanceof MultipartFile[]) { + MultipartFile[] files = (MultipartFile[]) value; + for (MultipartFile file : files) { + Object jsonObj = JSON.toJSON(file.getOriginalFilename()); + params.append(jsonObj.toString()).append(" "); + } + } else { + if (value != null) { + Object jsonObj = JSON.toJSON(value); + params.append(jsonObj.toString()).append(" "); + } + } + } + } + } + return params.toString(); + } + + + /** + * 判断是否需要过滤 + * + * @param o 对象信息。 + * @return 是需要过滤的对象,则返回true;否则返回false。 + */ + public boolean isFilterObject(final Object o) { + return o instanceof HttpServletRequest || o instanceof HttpServletResponse; + } +} \ No newline at end of file diff --git a/securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/enums/OperaType.java b/securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/enums/OperaType.java new file mode 100644 index 0000000..20ca91d --- /dev/null +++ b/securityControl-common/securityControl-common-log/src/main/java/com/securityControl/common/log/enums/OperaType.java @@ -0,0 +1,55 @@ +package com.securityControl.common.log.enums; + +/** + * 操作类型 + * @author 黑子 + */ +public class OperaType { + + /** + * 查询 + */ + public final static String QUERY="查询"; + + /** + * 修改 + */ + public final static String UPDATE="修改"; + /** + * 新增" + */ + public final static String INSERT="新增"; + /** + * 删除 + */ + public final static String DELETE="删除"; + /** + * 删除 + */ + public final static String DOWNLOAD="下载"; + + /** + * 导出 + */ + public final static String EXPORT="导出"; + + public final static String GRANT="授权"; + /** + * 下载 + */ + public final static String IMPORT="导入"; + /** + * 其他 + */ + public final static String OTHER="其他"; + + /** + * 其他 + */ + public final static String FLASH="刷新"; + + /** + * 其他 + */ + public final static String COPY="备份"; +}