开源:如何优雅的实现一个操作日志组件

Posted 码上实战

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开源:如何优雅的实现一个操作日志组件相关的知识,希望对你有一定的参考价值。

操作日志

  • 系统日志:主要用于开发者调试排查系统问题的,不要求固定格式和可读性
  • 操作日志:主要面向用户的,要求简单易懂,反映出用户所做的动作。
  • 通过操作日志可追溯到 某人在某时干了某事情,如:

    租户操作人时间操作内容
    A租户小明2022/2/27 20:15:00新增新增了一个用户:Mr.Wang
    B租户大米2022/2/28 10:35:00更新修改订单 [xxxxxx] 价格为 xx 元
    C租户老王2022/2/28 22:55:00查询查询了名为: [xx] 的所有交易
    的形式在模板中展示自定义函数,解析整个模板前,我们先来解析下自定义函数,将解析后的值替换掉模板中的字符串即可。

    if (template.contains("")) 
       Matcher matcher = PATTERN.matcher(template);
       while (matcher.find()) 
           String funcName = matcher.group(1);
           String param = matcher.group(2);
           if (customFunctionService.executeBefore(funcName)) 
              String apply = customFunctionService.apply(funcName, param);
           
       

    4.5 获取操作者信息

    一般我们都是将登录者信息存入应用上下文中,所以我们不必每次都在日志注解中指出,我们可统一设置,定义一个获取操作者接口,由使用者实现。

    public interface IOperatorService 
        // 获取当前操作者
        String getOperator();
        // 当前租户
        String getTenant();

    4.6 定义日志内容接收

    我们要将解析完成后的日志内容实体信息发送给我们的使用者,所以我们需要定义一个日志接收的接口,具体的实现交给使用者来实现,无论他接收到日志存储在数据库,MQ还是哪里,让使用者来决定。

    public interface ILogRecordService 
        /**
         * 保存 log
         * @param easyLogInfo 日志实体
         */

        void record(EasyLogInfo easyLogInfo);

    4.7 定义AOP拦截
    @Aspect
    @Component
    @AllArgsConstructor
    public class EasyLogAspect 

        @Pointcut("@annotation(**.EasyLog)")
        public void pointCut() 

        // 环绕通知
        @Around("pointCut() && @annotation(easyLog)")
        public Object around(ProceedingJoinPoint joinPoint, EasyLog easyLog) throws Throwable 

            //前置自定义函数解析
            try 
                result = joinPoint.proceed();
             catch (Throwable e) 
            
            //SpEL解析
            //后置自定义函数解析
            return result;
        

    4.8 自定义 spring boot starter

    创建自动配置类,将定义的一些来交给Spring容器管理:

    @Configuration
    @ComponentScan("**")
    public class EasyLogAutoConfiguration 

        @Bean
        @ConditionalOnMissingBean(ICustomFunction.class)
        @Role(BeanDefinition.ROLE_APPLICATION)
        public ICustomFunction customFunction()

            return new DefaultCustomFunction();
        

        @Bean
        @ConditionalOnMissingBean(IOperatorService.class)
        @Role(BeanDefinition.ROLE_APPLICATION)
        public IOperatorService operatorGetService() 

            return new DefaultOperatorServiceImpl();
        

        @Bean
        @ConditionalOnMissingBean(ILogRecordService.class)
        @Role(BeanDefinition.ROLE_APPLICATION)
        public ILogRecordService recordService() 

            return new DefaultLogRecordServiceImpl();
        

    上一篇我已经完整的介绍了如何自定义 spring boot starter ,可去参考:

    开源:如何自定义spring boot starter

    5. 我们可以学到什么?

    你可以拉取easy-log源码,用于学习,通过easy-log你可以学到:

  • 注解的定义及使用
  • AOP的应用
  • SpEL表达式的解析
  • 自定义 Spring boot starter
  • 设计模式
  • 6. 源码
  • GitHub: https://github.com/flyhero/easy-log
  • Gitee: https://gitee.com/flyhero/easy-log
  • vue选择性刷新组件&如何实现优雅的刷新页面

    在开发项目的过程中,有时修改后台的数据变化可能不会及时更新到页面上,此时就需要我们刷新页面更新数据,但是直接调用刷新window.location.reload()可能对操作的体验不是很好,所以就需要下面的方法。

    列举个场景,比如修改主体content内容,我想要刷新主体部分的组件,但是不刷新title和aside组件,怎么实现呢?

    实现方法就是在想要刷新的组件中封装一个方法,当需要刷新页面时直接调用这个方法就可以无痕迹刷新这个组件(页面)!

    代码:

    1、在app.vue中封装方法,此时调用可以刷新整个系统(整个页面)

    <template>
    	<div class="app-file">
    		<router-view v-if="isRouterAlive"></router-view>
    	</div>
    </template>
    
    <script>
    export default {
    	provide() {
    		return {
    			reloadAll: this.reloadAll
    		}
    	},
    	data() {
    		return {
    			isRouterAlive: true
    		}
    	},
    	methods: {
    		reloadAll() {
    			this.isRouterAlive = false
    			this.$nextTick(() => {
    				this.isRouterAlive = true
    			})
    		}
    	}
    }
    </script>
    
    <style lang="scss" scoped>
    </style>
    

    2、第二部,在想要实现刷新方法的组件引用及调用

    技术图片

     

     3、这样在调用就可以实现我们想要的效果,同理,也可应用到其他组件,如开头所列举的场景:

    技术图片

     

     这样就可以实现选择性的刷新头部,侧边导航栏或者是主体内容了!

     

    以上是关于开源:如何优雅的实现一个操作日志组件的主要内容,如果未能解决你的问题,请参考以下文章

    如何优雅地记录操作日志?

    如何优雅地记录操作日志

    使用loki+promtail实现云原生日志分析

    vue选择性刷新组件&如何实现优雅的刷新页面

    如何让日志打印更加优雅和实现数据链路追踪?

    如何让日志打印更加优雅和实现数据链路追踪?