SpringBoot记录日志

复制代码
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {        // 自定义操作日志记录注解

    public String title() ;                                // 模块名称
    public OperatorType operatorType() default OperatorType.MANAGE;    // 操作人类别
    public int businessType() ;     // 业务类型(0其它 1新增 2修改 3删除)
    public boolean isSaveRequestData() default true;   // 是否保存请求的参数
    public boolean isSaveResponseData() default true;  // 是否保存响应的参数

}
复制代码

1.自定义@Log注解

这个注解的作用是通过在方法上添加@Log注解,自动记录操作日志。通过设置不同的属性值,可以定制日志的内容,包括操作模块、操作人类别、业务类型以及是否保存请求和响应参数等信息。

2.OperatorType

public enum OperatorType {        // 操作人类别
    OTHER,        // 其他
    MANAGE,        // 后台用户
    MOBILE        // 手机端用户
} 

3.@EnableLogAspect

定义一个注解,用于启用日志切面功能。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(value = LogAspect.class)            // 通过Import注解导入日志切面类到Spring容器中
public @interface EnableLogAspect {
 
}

在启动类中加入注解

复制代码
 
@RefreshScope
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients("com.huiye")
@EnableMongoRepositories("com.huiye")
@ComponentScan({"com.huiye"})
@MapperScan("com.huiye.core.mapper")
@EnableAspectJAutoProxy
@EnableScheduling

public class ManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ManagerApplication.class , args);
}

}

 
复制代码

4.定义切面类

复制代码
 
@Aspect
@Component
@Slf4j
public class LogAspect {            // 环绕通知切面类定义
 
    @Autowired
    private AsyncOperLogService asyncOperLogService ;
 
    @Around(value = "@annotation(sysLog)")
    public Object doAroundAdvice(ProceedingJoinPoint joinPoint , Log sysLog) {
 
        // 构建前置参数
        SysOperLog sysOperLog = new SysOperLog() ;
 
        LogUtil.beforeHandleLog(sysLog , joinPoint , sysOperLog) ;
 
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
            // 执行业务方法
            LogUtil.afterHandleLog(sysLog , proceed , sysOperLog , 0 , null) ;
            // 构建响应结果参数
        } catch (Throwable e) {                                 // 代码执行进入到catch中,
            // 业务方法执行产生异常
            e.printStackTrace();                                // 打印异常信息
            LogUtil.afterHandleLog(sysLog , proceed , sysOperLog , 1 , e.getMessage()) ;
            throw new RuntimeException();
        }
 
        // 保存日志数据
        asyncOperLogService.save(sysOperLog);
 
        // 返回执行结果
        return proceed ;
    }
}
复制代码
复制代码

5.工具类

public class LogUtil {

//操作执行之后调用
public static void afterHandleLog(Log sysLog, Object proceed,
SysOperLog sysOperLog, int status ,
String errorMsg) {
if(sysLog.isSaveResponseData()) {
sysOperLog.setJsonResult(JSON.toJSONString(proceed));
}
sysOperLog.setStatus(status);
sysOperLog.setErrorMsg(errorMsg);
}

//操作执行之前调用
public static void beforeHandleLog(Log sysLog,
ProceedingJoinPoint joinPoint,
SysOperLog sysOperLog) {

// 设置操作模块名称
sysOperLog.setTitle(sysLog.title());
sysOperLog.setOperatorType(sysLog.operatorType().name());

// 获取目标方法信息
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature() ;
Method method = methodSignature.getMethod();
sysOperLog.setMethod(method.getDeclaringClass().getName());

// 获取请求相关参数
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)
RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
sysOperLog.setRequestMethod(request.getMethod());
sysOperLog.setOperUrl(request.getRequestURI());
sysOperLog.setOperIp(request.getRemoteAddr());

// 设置请求参数
if(sysLog.isSaveRequestData()) {
String requestMethod = sysOperLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
String params = Arrays.toString(joinPoint.getArgs());
sysOperLog.setOperParam(params);
}
}
sysOperLog.setOperName(AuthContextUtil.get().getUserName());
}
}

 

afterHandleLog:
在操作执行后记录日志,根据sysLog属性决定是否保存操作结果,同时设置sysOperLog的状态码和错误信息。


beforeHandleLog:
在操作执行前记录日志,获取并设置操作模块、类型、方法信息、请求参数等,并根据sysLog属性决定是否保存请求数据,最后设置操作人名称。

 

6.定义切面类中用到的接口和实现类

复制代码
 
public interface AsyncOperLogService extends IService<SysOperLog> {            // 保存日志数据
}

@Service
@RequiredArgsConstructor
public class AsyncOperLogServiceImpl extends ServiceImpl<SysOperLogMapper, SysOperLog> implements AsyncOperLogService {
private SysOperLogMapper sysOperLogMapper;
}

 

@Mapper
public interface SysOperLogMapper extends BaseMapper<SysOperLog> {
}

7.SysOperLog

 

定义一个与日志数据库表相对应的实体类

复制代码
 

@Data
@Schema(description = "SysOperLog")

public class SysOperLog extends BaseEntity {

private static final long serialVersionUID = 1L;

@TableId(value = "id", type = IdType.AUTO)
private Long id;

@Schema(description = "模块标题")
private String title;

@Schema(description = "方法名称")
private String method;

@Schema(description = "请求方式")
private String requestMethod;

private Integer businessType ; // 业务类型(0其它 1新增 2修改 3删除)

@Schema(description = "操作类别(0其它 1后台用户 2手机端用户)")
private String operatorType;

@Schema(description = "操作人员")
private String operName;

@Schema(description = "请求URL")
private String operUrl;

@Schema(description = "主机地址")
private String operIp;

@Schema(description = "请求参数")
private String operParam;

@Schema(description = "返回参数")
private String jsonResult;

@Schema(description = "操作状态(0正常 1异常)")
private Integer status;

@Schema(description = "错误消息")
private String errorMsg;

}

 

8.表结构

复制代码
 

CREATE TABLE `sys_oper_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键',
`title` varchar(50) DEFAULT '' COMMENT '模块标题',
`business_type` varchar(20) DEFAULT '0' COMMENT '业务类型(0其它 1新增 2修改 3删除)',
`method` varchar(100) DEFAULT '' COMMENT '方法名称',
`request_method` varchar(10) DEFAULT '' COMMENT '请求方式',
`operator_type` varchar(20) DEFAULT '0' COMMENT '操作类别(0其它 1后台用户 2手机端用户)',
`oper_name` varchar(50) DEFAULT '' COMMENT '操作人员',
`dept_name` varchar(50) DEFAULT '' COMMENT '部门名称',
`oper_url` varchar(255) DEFAULT '' COMMENT '请求URL',
`oper_ip` varchar(128) DEFAULT '' COMMENT '主机地址',
`oper_param` varchar(2000) DEFAULT '' COMMENT '请求参数',
`json_result` varchar(2000) DEFAULT '' COMMENT '返回参数',
`status` int DEFAULT '0' COMMENT '操作状态(0正常 1异常)',
`error_msg` varchar(2000) DEFAULT '' COMMENT '错误消息',
`oper_time` datetime DEFAULT NULL COMMENT '操作时间',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8mb3 COMMENT='操作日志记录';

复制代码
复制代码
复制代码
复制代码
posted @   Fyy发大财  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示