java用户行为日志记录方法_简单易用的开源用户操作日志记录系统

我们开发的业务系统通常会提供给很多人使用,那在使用的过程中,日志系统变得非常重要。

日志系统记录的用户行为有以下的作用:

从系统用户角度看:它展示了用户自身的操作历史和具体对象的变动历史,便于用户进行梳理

从系统管理员角度看:它可以记录了所有用户操作,便于我们定位异常行为

例如,在git的project操作中,我们就可以看到这样的操作日志展示:

e3670900c3706f70fde72cac5f9d64cb.png

对于这样的日志记录,我们可以在相关记录点添加对应的日志写入代码或者通过切面实现。然而,这样的日志展示是相对简单的,只是记录了操作行为的种类。而有时我们需要记录每个操作行为对操作对象引发的具体变动,例如展示出这样的结果:

75f276d9acaee66499ca353946d5dc00.png

这给日志记录带来了不小的挑战:

在一个系统中,可能涉及到多种对象(例如,学生、课程、老师),而每个对象的属性是完全不一样的

在一次操作中,可能改变了对象的一个或者多个属性,这也使得我们极难逐一记录

而今天,我们要介绍的是一套简单易用的对象日志记录系统,借助于它,我们可以方便地实现对象属性变动的记录与查询。

该系统来源于开源项目ObjectLogger,地址为 https://github.com/yeecode/ObjectLogger 。感兴趣的小伙伴可以前往Star该项目。

而ObjectLogger的核心引用了开源项目ObjectLoggerClient,地址为 https://github.com/yeecode/ObjectLoggerClient 可以一并Star。

最终实现的效果如下:

95704746c6aebede998f19503cb101b5.png

当然,该项目提供日志分析、记录、查询功能,前端页面的设计与展示交给使用者自己开发和优化,因此也保证了最大的自由度。接下来我们介绍该系统及其使用。

1 系统特点

该系统有着以下特点:

功能强大:部署完成后,可以支持日志的记录与查询,开发者只需再开发前端界面即可使用。

完全独立:该系统与业务系统完全独立,可插拔使用,不影响主业务流程。并且可以同时支持多个业务系统使用。

简单易用:系统采用SpringBoot实现,可以独立jar包启动。同时向业务系统提供jar包,便于日志的分析与写入。

自动解析:能自动解析被操作对象的零个、一个、多个属性变动,支持富文本对象的前后对比。

便于扩展:支持自定义对象变动说明、属性变动说明。支持更多对象属性类型的扩展

2 系统部署

2.1 数据库部分部署

自备数据库,mySql或者SQLserver数据库均可。

使用该项目的/database/init_data_table.sql文件初始化两个数据表。

2.2 ObjectLogger系统部署

下载github开源项目ObjectLogger的代码。

根据你的数据库种类、地址、密码等配置项目代码/src/main/resources/application.properties文件中的下面部分:

spring.datasource.driver-class-name ={db_driver}

spring.datasource.url =jdbc:mysql://{your_mysql_address}/{your_database_name}

spring.datasource.username ={your_database_username}

spring.datasource.password ={your_database_password}

使用maven打包该项目的jar包。

获取target目录下的jar包,使用java -jar ObjectLogger-1.0.1.jar启动项目。项目默认端口8080,可在配置文件中修改。

这样,我们已经可以查看到系统的启动页面,并可以通过/ObjectLogger/log/query查询系统中的日志,该接口支持传入参数对日志进行筛选过滤。不过,因为目前我们的系统刚刚搭建完成,应该没有任何的日志存入。

dc17eae8e4c2b772148eef739a9b3862.png

接下来我们便介绍如何配置业务系统,以便实现对象变化的分析与日志的写入。

2.3 业务系统配置

该部分主要讲解如何配置业务系统来实现将业务系统中的对象变化记录到ObjectLogger中。

2.3.1 业务系统添加maven依赖

在Pom中添加对ObjectLoggerClient jar包的引用。该jar包已经发布到了官方Maven仓库中,在Pom如下引用即可。

com.github.yeecode.objectLogger

ObjectLoggerClient

1.0.4

该依赖来源于项目ObjectLoggerClient。如果想了解详细原理可前去研究。

2.3.2 在业务系统中添加对ObjectLoggerClient中提供的bean的自动扫描

若业务应用为SpringBoot应用,则在SpringBoot的启动类前添加@ComponentScan注解,并在basePackages中增加ObjectLoggerClient的包地址:com.github.yeecode.objectLoggerClient,如:

a8696964edfcf88c438186bdb4f6c119.png

若业务应用为Spring应用,则在applicationContext.xml增加对ObjectLoggerClient包地址的扫描:

11c1e936a44409676c7124a1516b128d.png

2.3.3 添加对ObjectLoggerClient的配置

在application.properties中增加:

object.logger.add.log.api=http://{your_ObjectLogger_address}/ObjectLogger/log/add

object.logger.appName={your_app_name}

object.logger.add.log.api属性指向上一步的ObjectLogger的部署地址,用于将业务系统的日志发送到那里。

object.logger.appName指明了当前业务系统的应用名以便于区分日志来源,实现同时支持多个业务系统

2.3.4 声明一个扩展LocalTypeHandler的类,作为自由扩展的钩子

113a05b3cb04f799c1360f9a3af1c2c3.png

至此,整个系统部署结束。

3 系统使用

业务系统在任何需要进行日志记录的类中引入LogClient。例如:

@Autowired

private LogClient logClient;

接下来就可以自由使用了。

3.1 简单使用

直接将对象的零个、一个、多个属性变化放入actionItemModelList中发出即可。actionItemModelList置为null则表示此次对象无需要记录的属性变动。例如,业务应用中调用:

logClient.sendLogForItems("TaskModel",5,"actor name","addTask","add Task","via web page","some comments",null);

在ObjectLogger中使用如下查询条件:

http://{your_ObjectLogger_address}/ObjectLogger/log/query?appName=myBootApp&objectName=TaskModel&objectId=5

查询到日志:

3f8d5129cb91a9b812fb99fb3c1c27f8.png

3.2 对象变动自动记录

该功能可以自动完成新老对象的对比,并根据对比结果,将多个属性变动一起写入日志系统中。使用时,要确保传入的新老对象属于同一个类。

例如,业务系统这样调用:

fc5f1f26caa8932ea7980a45a36be11a.png

则我们可以使用下面查询条件:

http://{your_ObjectLogger_address}/ObjectLogger/log/query?appName=myBootApp&objectName=TaskModel&objectId=9

查询到如下结果:

bdfe3aac0c2edd8179cc446e9db7b54c.png

对象属性的自动对比需要@LogDescription注解的支持。对于对象中未加注解的属性会自动跳过对比。

例如,本次示例中的注解配置如下:

5969f781b1c286d1ad018bd69f783bc5.png

@LogDescription注解的属性介绍如下:

name:必填,对应写入日志后的attributeName值。

type:为AttributeTypeEnum的值,默认为AttributeTypeEnum.NORMAL。

AttributeTypeEnum.NORMAL:记录属性的新值和旧值,对比值为null

AttributeTypeEnum.TEXT: 用户富文本对比。记录属性值的新值和旧值,并将新旧值转化为纯文本后逐行对比差异,对比值中记录差异

AttributeTypeEnum.LOCALTYPE:表明该字段由用户自定义处理,此时localType生效。

localType:只有当type = AttributeTypeEnum.LOCALTYPE时生效。此时,该字段如果新旧值不一样,则会传递到LocalTypeHandler的实现类中。例如,示例中userId字段交由实现类处理,代码如下:

caa657a24abe825723fccfad94d919ba.png

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
具体代码实现需要结合具体的业务场景和代码架构来实现,下面是一份基于Spring AOP的伪代码示例: ```java // 1. 创建切面类,用于记录数据变化 @Aspect @Component public class DataChangeAspect { @Autowired private DataChangeLogService dataChangeLogService; // 2. 定义切入点,匹配需要记录数据变化的方法 @Pointcut("execution(* com.example.service.*.*(..))") public void dataChangePointcut() {} // 3. 定义前置通知,记录方法调用前的数据 @Before("dataChangePointcut()") public void beforeDataChange(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); // 通过args参数获取方法调用前的数据 // ... // 记录数据变化 dataChangeLogService.logDataChange(args, DataChangeType.CREATE); } // 4. 定义后置通知,记录方法调用后的数据 @AfterReturning(pointcut = "dataChangePointcut()", returning = "result") public void afterDataChange(JoinPoint joinPoint, Object result) { // 通过result参数获取方法调用后的数据 // ... // 记录数据变化 dataChangeLogService.logDataChange(result, DataChangeType.UPDATE); } // 5. 定义异常通知,记录方法调用异常的数据 @AfterThrowing(pointcut = "dataChangePointcut()", throwing = "ex") public void exceptionDataChange(JoinPoint joinPoint, Exception ex) { Object[] args = joinPoint.getArgs(); // 通过args参数获取方法调用前的数据 // ... // 记录数据变化 dataChangeLogService.logDataChange(args, DataChangeType.DELETE, ex.getMessage()); } } // 6. 创建数据变化日志服务类 @Service public class DataChangeLogService { public void logDataChange(Object data, DataChangeType type) { // 记录数据变化 // ... } public void logDataChange(Object data, DataChangeType type, String message) { // 记录数据变化和异常信息 // ... } } // 7. 创建数据变化类型枚举类 public enum DataChangeType { CREATE, UPDATE, DELETE } ``` 在这份代码中,我们创建一个切面类DataChangeAspect,用于记录需要进行数据变化记录方法调用,并在其中定义了前置通知、后置通知和异常通知,用于分别记录方法调用前后和异常情况下的数据变化。我们还需要创建一个数据变化日志服务类DataChangeLogService,用于具体的数据变化记录操作。最后,我们还需要定义一个数据变化类型枚举类DataChangeType,用于记录数据变化的类型。 需要注意的是,这份代码只是一个示例,具体实现需要根据具体业务场景和代码架构进行调整。而且在实现过程中,也需要考虑到数据安全和隐私保护的问题,避免敏感数据的泄露。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值