From d8e5c2917a5fd425691de19b766647c1891beea1 Mon Sep 17 00:00:00 2001 From: wanggeng <450292408@qq.com> Date: Sat, 23 Oct 2021 23:10:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E3=80=81=E8=B7=AF=E7=94=B1=E6=97=A5=E5=BF=97=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ink/wgink/pojo/bos/log/ApiLogBO.java | 51 +++++++++ .../ink/wgink/pojo/bos/log/RouteLogBO.java | 87 +++++++++++++++ .../wgink/properties/LoggingProperties.java | 26 +++++ .../main/java/ink/wgink/util/log/LogUtil.java | 72 ++++++++++++ .../ink/wgink/common/aspect/ApiLogAspect.java | 104 ++++++++++++++++++ .../wgink/common/aspect/ApiParamsAspect.java | 5 +- .../service/rbac/impl/RbacServiceImpl.java | 49 +++++++-- 7 files changed, 382 insertions(+), 12 deletions(-) create mode 100644 basic-pojo/src/main/java/ink/wgink/pojo/bos/log/ApiLogBO.java create mode 100644 basic-pojo/src/main/java/ink/wgink/pojo/bos/log/RouteLogBO.java create mode 100644 basic-properties/src/main/java/ink/wgink/properties/LoggingProperties.java create mode 100644 basic-util/src/main/java/ink/wgink/util/log/LogUtil.java create mode 100644 common/src/main/java/ink/wgink/common/aspect/ApiLogAspect.java diff --git a/basic-pojo/src/main/java/ink/wgink/pojo/bos/log/ApiLogBO.java b/basic-pojo/src/main/java/ink/wgink/pojo/bos/log/ApiLogBO.java new file mode 100644 index 00000000..ed047edc --- /dev/null +++ b/basic-pojo/src/main/java/ink/wgink/pojo/bos/log/ApiLogBO.java @@ -0,0 +1,51 @@ +package ink.wgink.pojo.bos.log; + +/** + * @ClassName: ControllerLogBO + * @Description: Controller日志 + * @Author: wanggeng + * @Date: 2021/10/23 12:09 上午 + * @Version: 1.0 + */ +public class ApiLogBO extends RouteLogBO { + + private static final long serialVersionUID = 6474663479566921791L; + + private String method; + private Long startTime; + private Long endTime; + private Long usedTime; + + public String getMethod() { + return method == null ? "" : method.trim(); + } + + public void setMethod(String method) { + this.method = method; + } + + public Long getStartTime() { + return startTime == null ? 0 : startTime; + } + + public void setStartTime(Long startTime) { + this.startTime = startTime; + } + + public Long getEndTime() { + return endTime == null ? 0 : endTime; + } + + public void setEndTime(Long endTime) { + this.endTime = endTime; + } + + public Long getUsedTime() { + return usedTime == null ? 0 : usedTime; + } + + public void setUsedTime(Long usedTime) { + this.usedTime = usedTime; + } + +} diff --git a/basic-pojo/src/main/java/ink/wgink/pojo/bos/log/RouteLogBO.java b/basic-pojo/src/main/java/ink/wgink/pojo/bos/log/RouteLogBO.java new file mode 100644 index 00000000..fbca4f5f --- /dev/null +++ b/basic-pojo/src/main/java/ink/wgink/pojo/bos/log/RouteLogBO.java @@ -0,0 +1,87 @@ +package ink.wgink.pojo.bos.log; + +import java.io.Serializable; + +/** + * @ClassName: RouteLogBO + * @Description: 路由日志 + * @Author: wanggeng + * @Date: 2021/10/23 11:50 上午 + * @Version: 1.0 + */ +public class RouteLogBO implements Serializable { + private static final long serialVersionUID = 7192738070388541098L; + + private String host; + private Integer port; + private String requestIp; + private String context; + private String uri; + private String requestTime; + private String userId; + private String userName; + + public String getHost() { + return host == null ? "" : host.trim(); + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return port == null ? 0 : port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getRequestIp() { + return requestIp == null ? "" : requestIp.trim(); + } + + public void setRequestIp(String requestIp) { + this.requestIp = requestIp; + } + + public String getContext() { + return context == null ? "" : context.trim(); + } + + public void setContext(String context) { + this.context = context; + } + + public String getUri() { + return uri == null ? "" : uri.trim(); + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getRequestTime() { + return requestTime == null ? "" : requestTime.trim(); + } + + public void setRequestTime(String requestTime) { + this.requestTime = requestTime; + } + + public String getUserId() { + return userId == null ? "" : userId.trim(); + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName == null ? "" : userName.trim(); + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/basic-properties/src/main/java/ink/wgink/properties/LoggingProperties.java b/basic-properties/src/main/java/ink/wgink/properties/LoggingProperties.java new file mode 100644 index 00000000..78360f1b --- /dev/null +++ b/basic-properties/src/main/java/ink/wgink/properties/LoggingProperties.java @@ -0,0 +1,26 @@ +package ink.wgink.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @ClassName: LoggingProperties + * @Description: 日志 + * @Author: wanggeng + * @Date: 2021/10/23 12:03 上午 + * @Version: 1.0 + */ +@Component +@ConfigurationProperties(prefix = "logging") +public class LoggingProperties { + + private Boolean enableApiLog; + + public Boolean getEnableApiLog() { + return enableApiLog == null ? false : enableApiLog; + } + + public void setEnableApiLog(Boolean enableApiLog) { + this.enableApiLog = enableApiLog; + } +} diff --git a/basic-util/src/main/java/ink/wgink/util/log/LogUtil.java b/basic-util/src/main/java/ink/wgink/util/log/LogUtil.java new file mode 100644 index 00000000..eac71623 --- /dev/null +++ b/basic-util/src/main/java/ink/wgink/util/log/LogUtil.java @@ -0,0 +1,72 @@ +package ink.wgink.util.log; + +import com.alibaba.fastjson.JSONObject; +import ink.wgink.pojo.bos.log.ApiLogBO; +import ink.wgink.pojo.bos.log.RouteLogBO; +import ink.wgink.util.date.DateUtil; +import ink.wgink.util.request.RequestUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; + +/** + * @ClassName: LogUtil + * @Description: 日志工具 + * @Author: wanggeng + * @Date: 2021/10/23 11:13 上午 + * @Version: 1.0 + */ +public class LogUtil { + private static final Logger LOG = LoggerFactory.getLogger(LogUtil.class); + + /** + * 路由日志 + * + * @param request + * @param uri + * @param userId + * @param userName + */ + public static void routeLog(HttpServletRequest request, String uri, String userId, String userName) { + RouteLogBO routeLogBO = new RouteLogBO(); + routeLogBO.setHost(request.getRemoteAddr()); + routeLogBO.setPort(request.getLocalPort()); + routeLogBO.setRequestIp(RequestUtil.getRequestIp(request)); + routeLogBO.setContext(request.getContextPath()); + routeLogBO.setUri(uri); + routeLogBO.setRequestTime(DateUtil.getTime()); + routeLogBO.setUserId(userId); + routeLogBO.setUserName(userName); + LOG.info("ROUTE-LOG:{}", JSONObject.toJSONString(routeLogBO)); + } + + /** + * 接口日志 + * + * @param request 请求 + * @param uri 路径 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @param userId + * @param userName + */ + public static void apiLog(HttpServletRequest request, String uri, long startTime, long endTime, String userId, String userName) { + long usedTime = endTime - startTime; + ApiLogBO apiLogBO = new ApiLogBO(); + apiLogBO.setHost(request.getRemoteAddr()); + apiLogBO.setPort(request.getLocalPort()); + apiLogBO.setRequestIp(RequestUtil.getRequestIp(request)); + apiLogBO.setContext(request.getContextPath()); + apiLogBO.setUri(uri); + apiLogBO.setRequestTime(DateUtil.getTime()); + apiLogBO.setMethod(request.getMethod()); + apiLogBO.setStartTime(startTime); + apiLogBO.setEndTime(endTime); + apiLogBO.setUsedTime(usedTime); + apiLogBO.setUserId(userId); + apiLogBO.setUserName(userName); + LOG.info("API-LOG:{}", JSONObject.toJSONString(apiLogBO)); + } + +} diff --git a/common/src/main/java/ink/wgink/common/aspect/ApiLogAspect.java b/common/src/main/java/ink/wgink/common/aspect/ApiLogAspect.java new file mode 100644 index 00000000..2df3ea49 --- /dev/null +++ b/common/src/main/java/ink/wgink/common/aspect/ApiLogAspect.java @@ -0,0 +1,104 @@ +package ink.wgink.common.aspect; + +import ink.wgink.common.component.SecurityComponent; +import ink.wgink.pojo.app.AppTokenUser; +import ink.wgink.pojo.bos.UserInfoBO; +import ink.wgink.properties.LoggingProperties; +import ink.wgink.util.ReflectUtil; +import ink.wgink.util.log.LogUtil; +import ink.wgink.util.request.RequestUtil; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; + +/** + * @ClassName: ApiLogAspect + * @Description: 接口日志切面 + * @Author: WangGeng + * @Date: 2019/3/14 9:33 AM + * @Version: 1.0 + **/ +@Aspect +@Component +@Order(2) +public class ApiLogAspect { + + private static final Logger LOG = LoggerFactory.getLogger(ApiLogAspect.class); + @Autowired + private SecurityComponent securityComponent; + @Autowired + private LoggingProperties loggingProperties; + + /** + * api切入点 + */ + @Pointcut("execution(public * *..controller..*.*(..))") + public void apiLogCutPoint() { + } + + @Around("apiLogCutPoint()") + public Object apiLogAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + if (loggingProperties == null || !loggingProperties.getEnableApiLog()) { + return proceedingJoinPoint.proceed(); + } + return apiResult(proceedingJoinPoint); + } + + private Object apiResult(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + Object result; + try { + long startTime = System.currentTimeMillis(); + result = proceedingJoinPoint.proceed(); + long endTime = System.currentTimeMillis(); + log(startTime, endTime); + } catch (Throwable e) { + throw e; + } + return result; + } + + /** + * 生成日志 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + private void log(long startTime, long endTime) { + HttpServletRequest request = RequestUtil.getRequest(); + String uri = request.getRequestURI().replace(request.getContextPath(), ""); + if (uri.startsWith("/route")) { + return; + } + String token = request.getHeader("token"); + UserInfoBO userInfoBO = securityComponent.getCurrentUser(); + String userId = ""; + String userName = ""; + if (userInfoBO != null) { + // 登录系统的用户 + userId = userInfoBO.getUserId(); + userName = userInfoBO.getUserName(); + } else if (!StringUtils.isBlank(token)) { + // APP用户 + try { + AppTokenUser appTokenUser = securityComponent.getAppTokenUser(token); + if (appTokenUser != null) { + userId = appTokenUser.getId(); + userName = appTokenUser.getName(); + } + } catch (ReflectUtil.ReflectException e) { + e.printStackTrace(); + } + } + LogUtil.apiLog(request, uri, startTime, endTime, userId, userName); + } + +} diff --git a/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java b/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java index 64cea5ed..e3e1050d 100644 --- a/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java +++ b/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java @@ -35,10 +35,10 @@ public class ApiParamsAspect { private static final Logger LOG = LoggerFactory.getLogger(ApiParamsAspect.class); @Pointcut("execution(public * *..*Controller.*(..))") - public void apiCutPoint() { + public void systemCutPoint() { } - @Before("apiCutPoint()") + @Before("systemCutPoint()") public void beforeApiCutPoint(JoinPoint joinPoint) throws ParamsException { beforeCutPoint(joinPoint); } @@ -91,5 +91,4 @@ public class ApiParamsAspect { return null; } - } diff --git a/common/src/main/java/ink/wgink/common/service/rbac/impl/RbacServiceImpl.java b/common/src/main/java/ink/wgink/common/service/rbac/impl/RbacServiceImpl.java index 3d85d8b1..5d4bc7cd 100644 --- a/common/src/main/java/ink/wgink/common/service/rbac/impl/RbacServiceImpl.java +++ b/common/src/main/java/ink/wgink/common/service/rbac/impl/RbacServiceImpl.java @@ -2,8 +2,11 @@ package ink.wgink.common.service.rbac.impl; import ink.wgink.common.service.rbac.IRbacService; import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.pojo.bos.LoginUser; import ink.wgink.pojo.bos.RoleGrantedAuthorityBO; import ink.wgink.properties.AccessControlProperties; +import ink.wgink.properties.LoggingProperties; +import ink.wgink.util.log.LogUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +33,8 @@ public class RbacServiceImpl implements IRbacService { private static final Logger LOG = LoggerFactory.getLogger(RbacServiceImpl.class); @Autowired private AccessControlProperties accessControlProperties; + @Autowired + private LoggingProperties loggingProperties; /** * 根路径 @@ -42,6 +47,7 @@ public class RbacServiceImpl implements IRbacService { if (object == null || "anonymousUser".equals(object.toString())) { return false; } + LoginUser loginUser = (LoginUser) object; boolean hasPermission = false; String requestURI = request.getRequestURI(); Collection grantedAuthorities = authentication.getAuthorities(); @@ -51,57 +57,59 @@ public class RbacServiceImpl implements IRbacService { // 校验权限 for (GrantedAuthority grantedAuthority : grantedAuthorities) { if (!(grantedAuthority instanceof RoleGrantedAuthorityBO)) { - LOG.debug("角色授权格式错误:{}", grantedAuthority); + LOG.trace("角色授权格式错误:{}", grantedAuthority); continue; } RoleGrantedAuthorityBO roleGrantedAuthority = (RoleGrantedAuthorityBO) grantedAuthority; if (StringUtils.contains(roleGrantedAuthority.getRoleId(), ISystemConstant.ADMIN)) { - LOG.debug("权限校验URI:{},当前用户为最高管理员,有所有权限", requestURI); + LOG.trace("权限校验URI:{},当前用户为最高管理员,有所有权限", requestURI); hasPermission = true; + String uri = request.getRequestURI().replace(request.getContextPath(), ""); break; } // 放行权限 if (hasPassPermission(contextPath, requestURI, roleGrantedAuthority, antPathMatcher)) { - LOG.debug("权限校验URI:{},有新增权限", requestURI); + LOG.trace("权限校验URI:{},有新增权限", requestURI); hasPermission = true; break; } if (hasMenuPermission(contextPath, requestURI, roleGrantedAuthority, antPathMatcher)) { - LOG.debug("权限校验URI:{},有菜单权限", requestURI); + LOG.trace("权限校验URI:{},有菜单权限", requestURI); hasPermission = true; break; } // 是否校验增删改查权限 if (!accessControlProperties.getRolePermission()) { - LOG.debug("不校验URI的增、删、改、查权限"); + LOG.trace("不校验URI的增、删、改、查权限"); hasPermission = true; break; } // 新增权限 if (hasInsertPermission(contextPath, requestURI, roleGrantedAuthority, antPathMatcher)) { - LOG.debug("权限校验URI:{},有新增权限", requestURI); + LOG.trace("权限校验URI:{},有新增权限", requestURI); hasPermission = true; break; } // 删除权限 if (hasDeletePermission(contextPath, requestURI, roleGrantedAuthority, antPathMatcher)) { - LOG.debug("权限校验URI:{},有删除权限", requestURI); + LOG.trace("权限校验URI:{},有删除权限", requestURI); hasPermission = true; break; } // 修改权限 if (hasUpdatePermission(contextPath, requestURI, roleGrantedAuthority, antPathMatcher)) { - LOG.debug("权限校验URI:{},有修改权限", requestURI); + LOG.trace("权限校验URI:{},有修改权限", requestURI); hasPermission = true; break; } // 查询权限,查权限最多,最后校验 if (hasQueryPermission(contextPath, requestURI, roleGrantedAuthority, antPathMatcher)) { - LOG.debug("权限校验URI:{},有查询权限", requestURI); + LOG.trace("权限校验URI:{},有查询权限", requestURI); hasPermission = true; break; } } + log(hasPermission, requestURI, contextPath, request, loginUser); return hasPermission; } @@ -216,4 +224,27 @@ public class RbacServiceImpl implements IRbacService { return false; } + /** + * 路由日志 + * + * @param hasPermission + * @param requestURI + * @param contextPath + * @param request + * @param loginUser + */ + private void log(boolean hasPermission, String requestURI, String contextPath, HttpServletRequest request, LoginUser loginUser) { + if (!hasPermission) { + return; + } + if (loggingProperties == null || !loggingProperties.getEnableApiLog()) { + return; + } + String uri = requestURI.replace(contextPath, ""); + if (!uri.startsWith("/route")) { + return; + } + LogUtil.routeLog(request, uri, loginUser.getUserId(), loginUser.getUserName()); + } + }