实现过程
自定义操作日志注解
ElementType.METHOD)
(RetentionPolicy.RUNTIME)
public @interface SysLog {
/**
* 描述
* @return {String}
*/
String value();
}
(
基于AOP定义切面
操作日志使用spring event
异步入库
public class SysLogAspect {
// 先拿到事件发布器
private final ApplicationEventPublisher publisher;
private final KeyStrResolver tenantKeyStrResolver;
("${spring.application.name:}")
private String serverName;
//Pointcut 切点接口提供了丰富的实现,基于注解的、基于Aspect表达式的等
("@annotation(sysLog)")
public Object around(ProceedingJoinPoint point, SysLog sysLog) {
// ProceedingJoinPoint 中获取信息
String strClassName = point.getTarget().getClass().getName();
String strMethodName = point.getSignature().getName();
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
GapSysLog syslog = SysLogUtils.getSysLog(serverName);
syslog.setTitle(sysLog.value());
// 发送异步日志事件
Long startTime = System.currentTimeMillis();
Object obj;
try {
obj = point.proceed();
}
catch (Exception e) {
syslog.setType(LogTypeEnum.ERROR.getType());
syslog.setException(e.getMessage());
throw e;
}
finally {
Long endTime = System.currentTimeMillis();
syslog.setEraTime(endTime - startTime);
syslog.setParams(JSONUtil.parseArray(point.getArgs()).toString());
// 发布事件
// 事件是SysLogEvent,发送者是syslog
// 不关心处理者,比如处理者可以是短信验证也可以是邮件验证。实现了解耦。
// 简历修改为:基于AOP和发布事件(封装要记录的日志信息,面试官问日志信息包含哪些)以及基于监听器异步监听记录操作日志
// 记录的主要信息有:服务名(读取配置文件)、类名、方法名
publisher.publishEvent(new SysLogEvent(syslog));
}
return obj;
}
}
监听器(异步监听)接收事件进行处理
public class SysLogListener {
//方法调用
private ISysLogController serviceTransfer;
// //FeignClient远程调用
// private final RemoteLogService serviceTransfer;
//在Spring中,基于@Async标注的方法,称之为异步方法
//这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。
// 接收事件,用此注解声明这是一个监听事件的方法
(SysLogEvent.class)
public void saveSysLog(SysLogEvent event) {
// 以下是业务逻辑
GapSysLog sysLog = event.getSysLog();
serviceTransfer.insert(sysLog);
}
}
日志实体类如下
/**
* @Description: 日志查询传输对象
* (GapSysLog)实体类
* @Author: GdlSky
* @Date 下午5:19 2021/8/31
*/
(value = "日志实体对象展示")
public class GapSysLog implements Serializable {
private static final long serialVersionUID = -78769795229339921L;
/**
* 编号
*/
(value = "id")
private String id;
/**
* 日志类型
*/
(value = "请求结果0:成功9:失败")
(message = "日志类型不能为空")
private String type;
/**
* 日志标题
*/
(value = "日志标题")
(message = "日志标题不能为空")
private String title;
/**
* 应用标识
*/
(value = "应用标识")
private String serviceId;
/**
* 操作人
*/
(value = "操作人")
private String createBy;
/**
* 用户类型
*/
(value = "用户类型")
private Long userType;
/**
* 用户代理
*/
(value = "用户代理")
private String userAgent;
/**
* 创建时间
*/
(pattern = "yyyy-MM-dd", timezone = "GMT+8")
(pattern = "yyyy-MM-dd")
(value = "创建时间", dataType = "LocalDate", example = "2020-12-07")
private Date createTime;
/**
* 操作IP地址
*/
(value = "操作IP地址")
private String remoteAddr;
/**
* 请求URI
*/
(value = "请求URI")
private String requestUri;
/**
* 操作方式
*/
(value = "操作方式")
private String method;
/**
* 提交数据
*/
(value = "提交数据")
private String params;
/**
* 方法执行时间
*/
(value = "方法执行时间")
private Long eraTime;
/**
* 删除标记
*/
(value = "删除标记:1、是 2、否")
private Long delFlag;
/**
* 异常信息
*/
(value = "异常信息")
private String exception;
/**
* 所属租户
*/
(value = "所属租户")
private Integer tenantId;
}