管理员日志重构--新增管理员日志注解

This commit is contained in:
wsw 2023-07-25 18:46:35 +08:00
parent 3eb7864582
commit 93752a9ca7
7 changed files with 302 additions and 41 deletions

View File

@ -27,10 +27,16 @@ CREATE TABLE `admin_logs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '管理员ID',
`module` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '模块',
`opt` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '操作指令',
`remark` mediumtext COLLATE utf8mb4_unicode_ci COMMENT '备注',
`title` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '请求方法标题',
`opt` int(2) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 0 COMMENT '操作指令0其它 1新增 2修改 3删除 4查询 5登录 6退出登录',
`method` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '请求方法',
`request_method` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '请求方式POST,GET,PUT,DELETE',
`url` varchar(266) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '请求URL',
`param` text COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '请求参数',
`result` text COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '返回参数',
`ip` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'ip',
`ip_area` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '地址',
`error_msg` varchar(2000) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '错误消息',
`created_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `a_m_o` (`admin_id`,`module`,`opt`)

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 杭州白书科技有限公司
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package xyz.playedu.api.annotation;
import xyz.playedu.api.constant.BusinessType;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
/**
* 标题
*/
public String title() default "";
/**
* 功能
*/
public BusinessType businessType() default BusinessType.OTHER;
}

View File

@ -0,0 +1,134 @@
/*
* Copyright (C) 2023 杭州白书科技有限公司
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package xyz.playedu.api.aspectj;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import xyz.playedu.api.annotation.Log;
import xyz.playedu.api.domain.AdminLog;
import xyz.playedu.api.service.AdminLogService;
import xyz.playedu.api.service.BackendAuthService;
import xyz.playedu.api.util.IpUtil;
import xyz.playedu.api.util.RequestUtil;
import xyz.playedu.api.util.StringUtil;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
@Aspect
@Component
@Slf4j
public class AdminLogAspect {
@Autowired private BackendAuthService authService;
@Autowired private AdminLogService adminLogService;
/**
* Controller层切点 注解拦截
*/
@Pointcut("@annotation(xyz.playedu.api.annotation.Log)")
public void logPointCut() {}
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
handleLog(joinPoint, null, jsonResult);
}
/**
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
handleLog(joinPoint, e, null);
}
protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
try {
// 获取注解信息
Log controllerLog = getAnnotationLog(joinPoint);
if (null == controllerLog) {
return;
}
// 日志
AdminLog adminLog = new AdminLog();
adminLog.setAdminId(authService.userId());
adminLog.setModule("BACKEND");
adminLog.setTitle(controllerLog.title());
adminLog.setOpt(controllerLog.businessType().ordinal());
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
adminLog.setMethod(className + "." + methodName + "()");
HttpServletRequest request = RequestUtil.handler();
if (null == request) {
return;
}
adminLog.setRequestMethod(request.getMethod());
adminLog.setUrl(request.getRequestURL().toString());
Map<String, String[]> parameterMap = request.getParameterMap();
if (StringUtil.isNotEmpty(parameterMap)) {
String params = JSONUtil.toJsonStr(parameterMap);
adminLog.setParam(StringUtils.substring(params, 0, 2000));
}
adminLog.setResult(JSONUtil.toJsonStr(jsonResult));
adminLog.setIp(IpUtil.getIpAddress());
adminLog.setIpArea(IpUtil.getRealAddressByIP(IpUtil.getIpAddress()));
if (null != e) {
adminLog.setErrorMsg(StringUtil.substring(e.getMessage(), 0, 2000));
}
adminLog.setCreatedAt(new Date());
// 保存数据库
adminLogService.save(adminLog);
} catch (Exception exp) {
// 记录本地异常日志
log.error("异常信息:"+exp.getMessage(),e);
}
}
/**
* 是否存在注解如果存在就获取
*/
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(Log.class);
}
return null;
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2023 杭州白书科技有限公司
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package xyz.playedu.api.constant;
public enum BusinessType
{
/**
* 其它
*/
OTHER,
/**
* 新增
*/
INSERT,
/**
* 修改
*/
UPDATE,
/**
* 删除
*/
DELETE,
/**
* 查询
*/
GET,
/**
* 登录
*/
LOGIN,
/**
* 退出登录
*/
LOGOUT
}

View File

@ -43,11 +43,27 @@ public class AdminLog implements Serializable {
/** 模块 */
private String module;
/** 操作指令 */
private String opt;
/** 标题 */
private String title;
/** 备注 */
private String remark;
/** 操作指令 */
private Integer opt;
/** 请求方法 */
private String method;
/** 请求方式 POST,GET,PUT,DELETE */
@JsonProperty("request_method")
private String requestMethod;
/** 请求URL */
private String url;
/** 请求参数 */
private String param;
/** 返回参数 */
private String result;
/** ip */
private String ip;
@ -56,6 +72,10 @@ public class AdminLog implements Serializable {
@JsonProperty("ip_area")
private String ipArea;
/** 备注 */
@JsonProperty("error_msg")
private String errorMsg;
@JsonProperty("created_at")
private Date createdAt;
@ -81,18 +101,36 @@ public class AdminLog implements Serializable {
&& (this.getModule() == null
? other.getModule() == null
: this.getModule().equals(other.getModule()))
&& (this.getTitle() == null
? other.getTitle() == null
: this.getTitle().equals(other.getTitle()))
&& (this.getOpt() == null
? other.getOpt() == null
: this.getOpt().equals(other.getOpt()))
&& (this.getRemark() == null
? other.getRemark() == null
: this.getRemark().equals(other.getRemark()))
&& (this.getMethod() == null
? other.getMethod() == null
: this.getMethod().equals(other.getMethod()))
&& (this.getRequestMethod() == null
? other.getRequestMethod() == null
: this.getRequestMethod().equals(other.getRequestMethod()))
&& (this.getUrl() == null
? other.getUrl() == null
: this.getUrl().equals(other.getUrl()))
&& (this.getParam() == null
? other.getParam() == null
: this.getParam().equals(other.getParam()))
&& (this.getResult() == null
? other.getResult() == null
: this.getResult().equals(other.getResult()))
&& (this.getIp() == null
? other.getIp() == null
: this.getIp().equals(other.getIp()))
&& (this.getIpArea() == null
? other.getIpArea() == null
: this.getIpArea().equals(other.getIpArea()))
&& (this.getErrorMsg() == null
? other.getErrorMsg() == null
: this.getErrorMsg().equals(other.getErrorMsg()))
&& (this.getCreatedAt() == null
? other.getCreatedAt() == null
: this.getCreatedAt().equals(other.getCreatedAt()));
@ -105,10 +143,16 @@ public class AdminLog implements Serializable {
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getAdminId() == null) ? 0 : getAdminId().hashCode());
result = prime * result + ((getModule() == null) ? 0 : getModule().hashCode());
result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode());
result = prime * result + ((getOpt() == null) ? 0 : getOpt().hashCode());
result = prime * result + ((getRemark() == null) ? 0 : getRemark().hashCode());
result = prime * result + ((getMethod() == null) ? 0 : getMethod().hashCode());
result = prime * result + ((getRequestMethod() == null) ? 0 : getRequestMethod().hashCode());
result = prime * result + ((getUrl() == null) ? 0 : getUrl().hashCode());
result = prime * result + ((getParam() == null) ? 0 : getParam().hashCode());
result = prime * result + ((getResult() == null) ? 0 : getResult().hashCode());
result = prime * result + ((getIp() == null) ? 0 : getIp().hashCode());
result = prime * result + ((getIpArea() == null) ? 0 : getIpArea().hashCode());
result = prime * result + ((getErrorMsg() == null) ? 0 : getErrorMsg().hashCode());
result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
return result;
}
@ -122,10 +166,16 @@ public class AdminLog implements Serializable {
sb.append(", id=").append(id);
sb.append(", adminId=").append(adminId);
sb.append(", module=").append(module);
sb.append(", title=").append(title);
sb.append(", opt=").append(opt);
sb.append(", remark=").append(remark);
sb.append(", method=").append(method);
sb.append(", requestMethod=").append(requestMethod);
sb.append(", url=").append(url);
sb.append(", param=").append(param);
sb.append(", result=").append(result);
sb.append(", ip=").append(ip);
sb.append(", ipArea=").append(ipArea);
sb.append(", errorMsg=").append(errorMsg);
sb.append(", createdAt=").append(createdAt);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");

View File

@ -19,18 +19,11 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import xyz.playedu.api.constant.BackendLogConstant;
import xyz.playedu.api.domain.AdminLog;
import xyz.playedu.api.domain.AdminUser;
import xyz.playedu.api.event.AdminUserLoginEvent;
import xyz.playedu.api.service.AdminLogService;
import xyz.playedu.api.service.AdminUserService;
import xyz.playedu.api.util.IpUtil;
import java.util.Date;
@Component
@Slf4j
@ -38,8 +31,6 @@ public class AdminUserLoginListener {
@Autowired private AdminUserService adminUserService;
@Autowired private AdminLogService adminLogService;
@EventListener
public void updateLoginInfo(AdminUserLoginEvent event) {
AdminUser adminUser = new AdminUser();
@ -51,20 +42,4 @@ public class AdminUserLoginListener {
adminUserService.updateById(adminUser);
}
@Async
@EventListener
public void log(AdminUserLoginEvent event) {
String area = IpUtil.getRealAddressByIP(event.getIp());
AdminLog adminLog = new AdminLog();
adminLog.setAdminId(event.getAdminId());
adminLog.setModule(BackendLogConstant.MODULE_LOGIN);
adminLog.setOpt(BackendLogConstant.OPT_LOGIN);
adminLog.setIp(event.getIp());
adminLog.setIpArea(area);
adminLog.setCreatedAt(new Date());
adminLogService.save(adminLog);
}
}

View File

@ -8,16 +8,22 @@
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="adminId" column="admin_id" jdbcType="INTEGER"/>
<result property="module" column="module" jdbcType="VARCHAR"/>
<result property="opt" column="opt" jdbcType="VARCHAR"/>
<result property="remark" column="remark" jdbcType="VARCHAR"/>
<result property="title" column="title" jdbcType="VARCHAR"/>
<result property="opt" column="opt" jdbcType="INTEGER"/>
<result property="method" column="method" jdbcType="VARCHAR"/>
<result property="requestMethod" column="request_method" jdbcType="VARCHAR"/>
<result property="url" column="url" jdbcType="VARCHAR"/>
<result property="param" column="param" jdbcType="VARCHAR"/>
<result property="result" column="result" jdbcType="VARCHAR"/>
<result property="ip" column="ip" jdbcType="VARCHAR"/>
<result property="ipArea" column="ip_area" jdbcType="VARCHAR"/>
<result property="errorMsg" column="error_msg" jdbcType="VARCHAR"/>
<result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,admin_id,module,
opt,remark,ip,
ip_area,created_at
id,admin_id,module,title,
opt,method,request_method,url,param,result,
ip,ip_area,error_msg,created_at
</sql>
</mapper>