新增接口日志、路由日志功能

This commit is contained in:
wanggeng 2021-10-23 23:10:19 +08:00
parent 6209e3fb1c
commit d8e5c2917a
7 changed files with 382 additions and 12 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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));
}
}

View 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);
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}