新增接口日志、路由日志功能
This commit is contained in:
parent
6209e3fb1c
commit
d8e5c2917a
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
72
basic-util/src/main/java/ink/wgink/util/log/LogUtil.java
Normal file
72
basic-util/src/main/java/ink/wgink/util/log/LogUtil.java
Normal file
@ -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));
|
||||
}
|
||||
|
||||
}
|
104
common/src/main/java/ink/wgink/common/aspect/ApiLogAspect.java
Normal file
104
common/src/main/java/ink/wgink/common/aspect/ApiLogAspect.java
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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<? extends GrantedAuthority> 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user