aop切面记日志
package com.infosec.ztpdp.policycenter.component.log; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * <p> * 自定义日志注解 * </p> * * <p> * 版权所有:北京信安世纪科技股份有限公司 * </p> * * @author lbw * @date 2022年6月30日 * */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface LogAnnotation { /** * <p>Title: logtype</p> * <p>Description: 日志类型 默认为"" 即为管理员操作日志,注册日志="registeruser"</p> * @return * @author lbw * @date 2022年7月8日 */ String logtype() default ""; /** * <p>Title: paramKey</p> * <p>Description: 记录日志信息 需要从参数中取值当做日志参数时 设置此参数为所需参数key</p> * @return * @author lbw * @date 2022年7月8日 */ String paramKey() default ""; }
package com.infosec.ztpdp.policycenter.component.log; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; 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.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.alibaba.fastjson.JSONObject; import com.infosec.ztpdp.policycenter.common.jsonresult.JsonErrotCode; import com.infosec.ztpdp.policycenter.common.jsonresult.JsonResult; import com.infosec.ztpdp.policycenter.common.login.LoginUserUtil; import com.infosec.ztpdp.policycenter.common.login.UserLoginBean; import com.infosec.ztpdp.policycenter.common.util.Const; import com.infosec.ztpdp.policycenter.common.util.GetMacAddress; import com.infosec.ztpdp.policycenter.common.util.UebaInternationKeyConst; import com.infosec.ztpdp.policycenter.common.util.log.Log; import com.infosec.ztpdp.policycenter.common.util.log.LogConst; import com.infosec.ztpdp.policycenter.component.LocaleMessageSourceService; import io.swagger.annotations.ApiOperation; /** * <p> * 切面记录日志 * </p> * * <p> * 版权所有:北京信安世纪科技股份有限公司 * </p> * * @author lbw * @date 2022年6月28日 * */ @Aspect @Configuration public class LogAspect { private final String EXTERNAL_INTERFACE = "/api/" ; private final String OPEN_API = "/openapi/" ; private final String CLIENT_NO_FILTER = "/client/" ; private final String VERIFICATIONCODE_NO_FILTER = "/v1/verificationCode" ; @Resource private LocaleMessageSourceService localeMessageSourceService; @Autowired private Log log; public LogAspect() { } @Pointcut("@within(com.infosec.ztpdp.policycenter.component.log.LogAnnotation) || @annotation(com.infosec.ztpdp.policycenter.component.log.LogAnnotation)") public void pointCutMethod() { } /** * 声明环绕通知 */ @Around("pointCutMethod()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { Long startTime = System.currentTimeMillis(); // 获取request对象 RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; Object ret = null; if(sra == null) { ret = pjp.proceed(); return ret; } HttpServletRequest request = sra.getRequest(); String requestUri = request.getServletPath(); UserLoginBean localUser = LoginUserUtil.getLoginUserBean(request); boolean exceptionFlag = false; String requestParam = null ; if(requestUri.startsWith(EXTERNAL_INTERFACE) || requestUri.startsWith(OPEN_API)) { requestParam = getParam(pjp).toString() ; } try { ret = pjp.proceed(); } catch (Exception e) { // TODO: handle exception if(requestUri != null && requestUri.indexOf(Const.EXPORT_1) != -1) { exceptionFlag = true; }else { throw e; } } Long endTime = System.currentTimeMillis(); //设置请求路径 if(StringUtils.isEmpty(requestUri) || requestUri.contains(CLIENT_NO_FILTER) || requestUri.contains(VERIFICATIONCODE_NO_FILTER)) { // }else { addLog(request,requestUri,exceptionFlag,localUser,pjp,endTime-startTime,ret,requestParam); } return ret; } /** * 获取参数名和参数值 */ public JSONObject getParam(ProceedingJoinPoint proceedingJoinPoint) { JSONObject paramObj = new JSONObject() ; Object[] values = proceedingJoinPoint.getArgs(); String[] names = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterNames(); for (int i = 0; i < names.length; i++) { String key = names[i] ; // 剔除httprequest if("request".equals(key) || "response".equals(key)){ continue ; } paramObj.put(key, values[i]); } return paramObj; } private void addLog(HttpServletRequest request,String requestUri,boolean exceptionFlag,UserLoginBean localUser ,ProceedingJoinPoint pjp,Long time,Object ret,String requestParam) throws IOException { String apiName; String logType; MethodSignature signature = (MethodSignature) pjp.getSignature(); Method method = signature.getMethod(); ApiOperation apiOperation = method.getAnnotation(ApiOperation.class); apiName = Objects.nonNull(apiOperation) ? apiOperation.value() : ""; LogAnnotation annotation = method.getAnnotation(LogAnnotation.class); if(annotation == null) { annotation = pjp.getTarget().getClass().getAnnotation(LogAnnotation.class); } logType = annotation.logtype(); String msg = ""; String code = ""; String model = ""; String appName = ""; String operation = ""; int logLevel = Log.LOG_LEVEL_WARN; int result = Log.RESULT_FAIULE; String[] split = requestUri.split("/"); appName = !StringUtils.isEmpty(split[1])? split[1] : appName; model = !StringUtils.isEmpty(split[2])? split[2] : model; operation = !StringUtils.isEmpty(split[3])? split[3] : operation; // 存放扩展参数 JSONObject extendParam = new JSONObject() ; JsonResult res = null; if(ret!= null && ret instanceof JsonResult) { res = (JsonResult) ret ; code = res.getCode(); msg = res.getMsg(); extendParam.put("requestUrl", requestUri) ; extendParam.put("requestParam", requestParam) ; extendParam.put("requestResult", res.toJsonString()) ; }else if(ret!= null && ret instanceof JSONObject){ JSONObject resJson = (JSONObject) ret ; code = resJson.getString("code"); msg = resJson.getString("msg"); extendParam.put("requestUrl", requestUri) ; extendParam.put("requestParam", requestParam) ; extendParam.put("requestResult", resJson.toJSONString()) ; }else if(ret!= null && ret instanceof String){ JSONObject resJson = JSONObject.parseObject((String)ret) ; code = resJson.getString("resultcode"); code = "000000".equals(code) ? JsonErrotCode.SUCCESS_CODE:JsonErrotCode.PARAM_ERROR ; msg = resJson.getString("resultmsg"); extendParam.put("requestUrl", requestUri) ; extendParam.put("requestParam", requestParam) ; extendParam.put("requestResult", resJson.toJSONString()) ; }else { if(requestUri.contains(Const.GETQRCODE)) { extendParam.put("requestUrl", requestUri) ; extendParam.put("requestParam", requestParam) ; } } //没有响应 且操作类型为导出 if(ret == null && Const.EXPORT.equals(operation)) { //根据是否异常来设置code和msg if(exceptionFlag) { code = JsonErrotCode.FAIL_CODE; }else { code = JsonErrotCode.SUCCESS_CODE; } } String localUserLoginName = ""; String localUserName = ""; String localUserRoles = ""; String userClientIp = ""; if(Const.GET.equals(operation)) { operation = Log.HOWS_READ; }else if (Const.POST.equals(operation)) { operation = Log.HOWS_MODIFY; }else if (Const.DEL.equals(operation)) { operation = Log.HOWS_DEL; }else if (Const.ADD.equals(operation)) { operation = Log.HOWS_ADD; }else if (Const.LOGIN.equals(operation)) { operation = Log.HOWS_LOGIN; }else if (Const.SINGLEPOINT.equals(operation)) { operation = Log.HOWS_LOGOUT; }else if (Const.EXPORT.equals(operation)) { operation = Log.HOWS_EXPORT; }else if (Const.IMPORT.equals(operation)) { operation = Log.HOWS_IMPORT; }else if (Const.DOWNLOAD.equals(operation)) { operation = Log.HOWS_DOWNLOAD; }else { operation = Log.HOWS_OTHERS; } if(LogConst.MODEL_FLAG_PORTAL.equals(logType) ) { model = LogConst.MODEL_UEBA; } //没有登录调用接口(对外API,注册) if (localUser == null) { //对外API if( LogConst.LOGTYPE_API.equals(appName) ) { String header = request.getHeader(Const.APPID); localUserLoginName = header; localUserName = header; appName = header; model = LogConst.LOGTYPE_API; userClientIp = GetMacAddress.getIpAddr(request); }else if(LogConst.OPEN_API.equals(appName)) { localUserLoginName = LogConst.ZEROTRUST_CLIENT; localUserName = LogConst.ZEROTRUST_CLIENT; appName = LogConst.ZEROTRUST_CLIENT; model = LogConst.LOGTYPE_API; if(requestParam != null) { JSONObject reqestObj = JSONObject.parseObject(requestParam) ; if(requestUri.contains(Const.DYNAMICPDP_FORNETGATE) || requestUri.contains(Const.DEVICEENVCHANGED) ) { userClientIp = reqestObj.getJSONObject("param").getJSONObject("dattrs").getString("internetIp") ; } if(StringUtils.isEmpty(userClientIp)) { userClientIp = reqestObj.getString("intranetIp") ; } if(StringUtils.isEmpty(userClientIp)) { JSONObject paramJson1 = reqestObj.getJSONObject("param") ; if(paramJson1!=null) { userClientIp = paramJson1.getString("intranetIp") ; if(StringUtils.isEmpty(userClientIp)) { userClientIp = paramJson1.getString("internetIp") ; } } } extendParam.put("deviceId", reqestObj.getString("deviceId")) ; } }else if(LogConst.MODEL_FLAG_PORTAL.equals(logType) ) { if(requestUri.indexOf(Const.GET_1) != -1) { operation = Log.HOWS_READ; }else if (requestUri.indexOf(Const.UPDATE) != -1) { operation = Log.HOWS_MODIFY; }else if (requestUri.indexOf(Const.ADD_1) != -1) { operation = Log.HOWS_ADD; } localUserRoles = "commonuser"; //普通用户调用日志 没有登录时取参数内的登录名做日志参数 String paramKey = annotation.paramKey(); Map<String, Object> param = getParam(pjp); localUserLoginName = (String) param.get(paramKey); localUserName = localUserLoginName; } userClientIp = GetMacAddress.getIpAddr(request); }else { localUserLoginName = localUser.getLoginName(); localUserName = localUser.getUsername(); localUserRoles = localUser.getSystemrole(); userClientIp = localUser.getClientip(); } // 设置请求状态 if(JsonErrotCode.SUCCESS_CODE.equals(code)) { logLevel = Log.LOG_LEVEL_INFO; result = Log.RESULT_SUCCESS; if(StringUtils.isEmpty(msg)) { msg = apiName + "成功"; } } else if(JsonErrotCode.PARAM_ERROR.equals(code)) { logLevel = Log.LOG_LEVEL_WARN; result = Log.RESULT_FAIULE; if(StringUtils.isEmpty(msg)) { msg = apiName + "失败"; } } else if(JsonErrotCode.FAIL_CODE.equals(code)) { logLevel = Log.LOG_LEVEL_ERROR; result = Log.RESULT_FAIULE; msg = apiName+" 异常 " + (StringUtils.isEmpty(msg) ? "" : msg); if(res != null) { res.setMsg(localeMessageSourceService.getMessage(UebaInternationKeyConst.SYS_EXCEPTION)); } if(!LogConst.LOGTYPE_API.equals(LogConst.LOGTYPE_API)) { model = LogConst.MODEL_UEBA; } } log.writeLog(this.getClass().getName(), logLevel, model, localUserLoginName, userClientIp, operation, result, msg, localUserName, localUserRoles, appName,requestUri,extendParam); } }
package com.infosec.ztpdp.policycenter.component.login; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Objects; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; 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.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.infosec.ztpdp.policycenter.common.jsonresult.JsonErrotCode; import com.infosec.ztpdp.policycenter.common.jsonresult.JsonResult; import com.infosec.ztpdp.policycenter.common.login.LoginUserUtil; import com.infosec.ztpdp.policycenter.common.login.UserLoginBean; import com.infosec.ztpdp.policycenter.common.redisbase.Db0CacheUtils; import com.infosec.ztpdp.policycenter.common.util.Const; import com.infosec.ztpdp.policycenter.common.util.CookieUtil; import com.infosec.ztpdp.policycenter.common.util.SsoInternationKeyConst; import com.infosec.ztpdp.policycenter.common.util.log.Log; import com.infosec.ztpdp.policycenter.common.util.log.LogConst; import com.infosec.ztpdp.policycenter.component.LocaleMessageSourceService; import io.swagger.annotations.ApiOperation; /** * <p> * 切面记录日志 * </p> * * <p> * 版权所有:北京信安世纪科技股份有限公司 * </p> * * @author lbw * @date 2022年6月28日 * */ @Aspect @Configuration public class LoginOutLogAspect { @Autowired private Db0CacheUtils db0CacheUtils; @Resource private LocaleMessageSourceService localeMessageSourceService; @Autowired private Log log; public LoginOutLogAspect() { } @Pointcut("@within(com.infosec.ztpdp.policycenter.component.login.LoginOutLogAnnotation) || @annotation(com.infosec.ztpdp.policycenter.component.login.LoginOutLogAnnotation)") public void pointCutMethod() { } // 声明环绕通知 @Around("pointCutMethod()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { Long startTime = System.currentTimeMillis(); // 获取request对象 RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; Object ret = null; if(sra == null) { ret = pjp.proceed(); return ret; } HttpServletRequest request = sra.getRequest(); UserLoginBean localUser = LoginUserUtil.getLoginUserBean(request); String requestURI = request.getServletPath(); String logType; MethodSignature signature = (MethodSignature) pjp.getSignature(); Method method = signature.getMethod(); LoginOutLogAnnotation annotation = method.getAnnotation(LoginOutLogAnnotation.class); if(annotation == null) { annotation = pjp.getTarget().getClass().getAnnotation(LoginOutLogAnnotation.class); } logType = annotation.logtype(); if(LogConst.LOGTYPE_USER_LOGOUT.equals(logType) || LogConst.LOGTYPE_ADMIN_LOGOUT.equals(logType)) { String token = CookieUtil.getCookieValue(request, Const.TGCM_ID); if (!StringUtils.isEmpty(token)) { String userinfo = db0CacheUtils.get(token); if(!StringUtils.isEmpty(userinfo)) { // json对象转字符串 JSONObject jsonObject = JSONObject.parseObject(userinfo); localUser = JSONObject.parseObject(JSON.toJSONString(jsonObject.get("idInfo")),UserLoginBean.class); } } } boolean exceptionFlag = false; String requestParam = null ; if(requestURI.startsWith(Const.EXTERNAL_INTERFACE)) { requestParam = getParam(pjp).toString() ; } try { ret = pjp.proceed(); } catch (Exception e) { if(requestURI != null && requestURI.indexOf("/export/") != -1) { exceptionFlag = true; }else { throw e; } } Long endTime = System.currentTimeMillis(); //设置请求路径 if(StringUtils.isEmpty(requestURI) || requestURI.contains(Const.CLIENT_NO_FILTER)) { // }else { addLog(request,requestURI,exceptionFlag,localUser,pjp,endTime-startTime,ret,requestParam); } return ret; } //获取参数名和参数值 public JSONObject getParam(ProceedingJoinPoint proceedingJoinPoint) { JSONObject paramObj = new JSONObject() ; Object[] values = proceedingJoinPoint.getArgs(); String[] names = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterNames(); for (int i = 0; i < names.length; i++) { paramObj.put(names[i], values[i]); } return paramObj; } private void addLog(HttpServletRequest request,String requestURI,boolean exceptionFlag,UserLoginBean localUser ,ProceedingJoinPoint pjp,Long time,Object ret,String requestParam) throws IOException { String apiName; String logType; MethodSignature signature = (MethodSignature) pjp.getSignature(); Method method = signature.getMethod(); ApiOperation apiOperation = method.getAnnotation(ApiOperation.class); apiName = Objects.nonNull(apiOperation) ? apiOperation.value() : ""; LoginOutLogAnnotation annotation = method.getAnnotation(LoginOutLogAnnotation.class); if(annotation == null) { annotation = pjp.getTarget().getClass().getAnnotation(LoginOutLogAnnotation.class); } logType = annotation.logtype(); String msg = ""; String code = ""; String model = ""; String appName = ""; String operation = ""; int logLevel = Log.LOG_LEVEL_WARN; int result = Log.RESULT_FAIULE; String[] split = requestURI.split("/"); appName = !StringUtils.isEmpty(split[1])? split[1] : appName; model = !StringUtils.isEmpty(split[2])? split[2] : model; operation = !StringUtils.isEmpty(split[3])? split[3] : operation; // 存放扩展参数 JSONObject extendParam = new JSONObject() ; JsonResult res = null; if(ret!= null && ret instanceof JsonResult) { res = (JsonResult) ret ; code = res.getCode(); msg = res.getMsg(); extendParam.put("requestUrl", requestURI) ; extendParam.put("requestParam", requestParam) ; extendParam.put("requestResult", res.toJsonString()) ; } //没有响应 且操作类型为导出 if(ret == null && ("export".equals(operation) || LogConst.LOGTYPE_USER_LOGOUT.equals(logType) || LogConst.LOGTYPE_ADMIN_LOGOUT.equals(logType))) { //根据是否异常来设置code和msg if(exceptionFlag) { code = JsonErrotCode.FAIL_CODE; }else { code = JsonErrotCode.SUCCESS_CODE; } } String localUserLoginName = ""; String localUserName = ""; String localUserRoles = ""; String userClientIp = ""; //根据响应code首字母判断成功失败 if(code.startsWith("I")) { logLevel = Log.LOG_LEVEL_INFO; result = Log.RESULT_SUCCESS; if(StringUtils.isEmpty(msg)) { msg = apiName + "成功"; } } else if(code.startsWith("W")) { logLevel = Log.LOG_LEVEL_WARN; result = Log.RESULT_FAIULE; if(StringUtils.isEmpty(msg)) { msg = apiName + "失败"; } } else if(code.startsWith("E")) { logLevel = Log.LOG_LEVEL_ERROR; result = Log.RESULT_FAIULE; msg = apiName+" 异常 " + (StringUtils.isEmpty(msg) ? "" : msg); if(res != null) { res.setMsg(localeMessageSourceService.getMessage(SsoInternationKeyConst.SYS_EXCEPTION)); } } switch (operation) { case "get": operation = Log.HOWS_READ; break; case "update": operation = Log.HOWS_MODIFY; break; case "del": operation = Log.HOWS_DEL; break; case "add": operation = Log.HOWS_ADD; break; case "login": operation = Log.HOWS_LOGIN; break; case "export": operation = Log.HOWS_EXPORT; break; case "import": operation = Log.HOWS_IMPORT; break; case "download": operation = Log.HOWS_DOWNLOAD; break; default: operation = Log.HOWS_OTHERS; break; } localUserLoginName = localUser.getLoginName(); localUserName = localUser.getUsername(); localUserRoles = localUser.getSystemrole(); userClientIp = localUser.getClientip(); if(LogConst.LOGTYPE_ADMIN_LOGOUT.equals(logType)) { appName = LogConst.MODEL_FLAG_PORTAL; model = LogConst.LOGTYPE_LOGOUT; operation = Log.HOWS_LOGOUT; if(LogConst.LOGTYPE_ADMIN_LOGOUT.equals(logType)) { appName = LogConst.MODEL_FLAG_MANAGER; if (localUserRoles.equals(Const.ROLE_SUPERADMIN)) { msg = "超级管理员登出系统"; } else if (localUserRoles.equals(Const.ROLE_SYSADMIN) || localUserRoles.equals(Const.ROLE_SECADMIN) || localUserRoles.equals(Const.ROLE_AUDITADMIN)) { msg = "三员管理员登出系统"; } else { msg = "组织机构管理员登出系统"; } if(logLevel == Log.LOG_LEVEL_INFO) { msg += "成功"; } else if (logLevel == Log.LOG_LEVEL_WARN) { msg += "失败"; }else if (logLevel == Log.LOG_LEVEL_ERROR) { msg += "异常"; } } } log.writeLog(this.getClass().getName(), logLevel, model, localUserLoginName, userClientIp, operation, result, msg, localUserName, localUserRoles, appName,requestURI,extendParam); } }
public void writeLog(String orgClassName, int loglevel, String logcode, String uid, String clientip, String hows, int result, String describe, String username, String role, String appName, String url, JSONObject extendParam) { JSONObject logJsonObject = CommonUtil.buildAopLogObject(orgClassName, loglevel, logcode, uid, clientip, hows, result, describe, username, role, serviceIp, appName, url, extendParam); String logModel = ""; boolean isAdmin = StringUtils.isEmpty(role) ? false : judgeAdmin(role); if (StringUtils.isEmpty(url)) { // 截取日志编码中代表操作模块的编号。 logModel = logcode.substring(1, 3); } else { logModel = logcode; logcode = url; logJsonObject.put(LogConst.LOG_LOGCODE, logcode); logJsonObject.put(LogConst.LOG_LOGMODEL, logModel); } switch (logModel) { case LogConst.LOGTYPE_API: // 接口访问日志记录 break; case LogConst.LOGTYPE_LOGOUT: // 管理员登出日志记录 SynThreadPool.addAuthorityChangeSynRunnable( new ManagerLogAccessSynRunnable(iManagerAccessLogService, logJsonObject)); break; default: if (isAdmin) { } } }