• 无论是异常监控还是业务监控,通通搞定


    大家好,我是【架构摆渡人】,一只十年的程序猿。这是实践经验系列的第十二篇文章,这个系列会给大家分享很多在实际工作中有用的经验,如果有收获,还请分享给更多的朋友。

    监控三板斧

    在监控领域,最常用的三种方式就是Metrics, Tracing,Logging,可以称之为三板斧。

    Metrics

    系统度量,通过指标来度量系统是否正常,比如现在主流的Prometheus就是基于指标来构建监控体系。

    Tracing

    链路跟踪,用户的一次请求将贯穿这个链路,想要进行优化或者知道请求在哪个环节出问题,链路跟踪必不可少。很多全链路跟踪都借鉴了Google Dapper的思想。

    目前主流的链路跟踪有skywalking,Jaeger,Cat等框架。这里面有需要客户端埋点,也有通过Agent代理方式实现。

    Logging

    日志,无论是系统异常或者程序异常输出的日志,还是业务相关的日志,都能够直观的反应当前业务的状态,日志在监控领域中用的也比较多。比如说可以基于ELK啊,一些云服务的日志平台去集中收集管理日志,在出问题的时候方便溯源,同时也能基于关键词等进行告警。

    其实上面三种方式都是相辅相成的,各自有各自的适用场景。今天我们主要聊聊日志如何简单,快速的可以实现系统异常和业务的监控,比较适合一些初创团队,最小的成本方式实现监控。

    日志埋点

    硬编码埋点

    可以封装一个工具类,对接口进行埋点。可以输出一些关键信息,比如:

    • 请求时间
    • 请求用户
    • 请求的接口
    • 请求的RT
    • 请求是否成功
    • 请求的错误码
    • 是否压测请求
    • 等等。。。。
      工具类伪代码如下:
    public class BizLogUtils {
        public static <T> T run(Supplier<T> supplier, BizLogContent content, BiConsumer<T, BizLogContent> callbackResult) {
            long start = System.currentTimeMillis();
            try {
                T result = supplier.get();
                if (result instanceof ResponseData) {
                    ResponseData resp = (ResponseData)result;
                    content.setBizCode(resp.getCode());
                }
                callbackResult.accept(result, content);
                return result;
            } catch (Exception e) {
                if (e instanceof BizException) {
                    BizException he = (BizException)e;
                    content.setBizCode(he.getCode());
                } else {
                    content.setBizCode(ErrorCode.SERVER_ERROR_CODE.getCode());
                }
                content.setErrorMessage(e.getMessage());
                throw e;
            } finally {
                content.setExecTime(System.currentTimeMillis() - start);
                content.setEnv(EnvConfig.getEnv());
                BizLogger.info(content);
            }
        }
    }
    
    

    ResponseData 是接口层的统一响应类,所以这边可以直接强制装换。

    BizLogContent 就是你要输出的日志内容。

    在这里把异常给转换成错误码进行打印,如果有特殊的需求,也可以定义一个callback让使用自行进行异常到异常码的转换操作,更灵活。

    使用方式:

    BizLogContent bizLogContent = new BizLogContent(xx,xx,xx);
    return BizLogUtils.run(() -> {
       // 业务逻辑
    }, bizLogContent, (resp, content)-> {
        // resp 上面业务逻辑的响应结果,有的场景需要获取结果中的内容埋点
        // content 也就是bizLogContent,拿到结果set进去
    });
    

    调整logback的配置,将日志要单独输出到一个文件,方便采集。格式可以是Json,也就是文本,如果是文本,可以用一个特殊的分隔符进行分隔,比如 2022-01-01|makeOrder|1001|success 。

    自定义注解埋点

    当硬编码的工具类有了,让使用更方便的做法就是自定义注解。通过定义注解,配置要采集的字段信息,通过注解加切面的方式来统一进行处理,这样就减少了代码的侵入性。

    这边就不贴代码了,无非就是自定义注解,然后进行数据的提取。这里可以用SPEL表达式进行提取。

    比如:

    @BizLog(domain = BizLogConstant.SYNC, biz = BizLogConstant.SYNC_ORDER,
            bizId = @BizLogField(key = "bizId", value = "#response.data.orderId", 
            addition = {
            @BizLogField(key = "userId", value = "#request.userId"),
            @BizLogField(key = "count", value = "#request.count")
    }))
    public ResponseData syncOrder(SyncOrderRequest request) {
      
    }
    

    总结

    大家可以看到,通过日志埋点成本是非常低的。只需要开发一套日志卖点的工具类即可。然后将埋点的数据进行日志输出,然后进行日志收集就可以实现告警,和图表大盘的构建之类的,非常方便。

    同样,本文的思路还可以应用到其他场景,比如操作日志的输出,也可以采用类似的方式去实现埋点,日志收集,数据展示。

    原创:架构摆渡人(公众号ID:jiagoubaiduren),欢迎分享,转载请保留出处。

    本文已收录至学习网站 http://cxytiandi.com/ ,里面有Spring Boot, Spring Cloud,分库分表,微服务,面试等相关内容。

  • 相关阅读:
    【无标题】
    64位Office API声明语句第110讲
    考了6次终于屠鸭成功!重获新生!
    c++ 哈希表(Hash Table)
    【c++】cpp类和对象
    js判断变量数据类型的几种常用方法
    【工具】一键生成动态歌词字幕
    大厂面试题-索引的底层实现,为什么选择B+Tree而不是红黑树?
    企业微信H5开发遇到的坑
    《30天吃掉那只 TensorFlow2.0》五、TensorFlow的中阶API
  • 原文地址:https://www.cnblogs.com/jiagoubaiduren/p/15998276.html