当前位置: 首页 > article >正文

OkHttp Interceptor日志上报

最近为了做一些网络上的优化,所以就得提前埋点,为后续网络优化提供数据支持。
主要是对发起请求埋点,请求错误埋点,客户端请求耗时埋点。
事件上报到阿里云,接入的是阿里的应用实时监控服务。

网络请求使用的是OhHttp + Retrofit ,现在很多都是这么实现的了吧。
网络的埋点切入口,很容易就想到了 Interceptor,用起来了才觉得 Interceptor 是真的香,以前还只是觉得这个设计模式是真好。用到了才感觉是太香了。

上代码:

class ReportingInterceptor(val source: ACRSource) : Interceptor {

    private val gson = Gson()

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val url = request.url.toString()

        AlibabaCloudRumUtil.requestStart(source, snapshots = url)

        val startTime = System.currentTimeMillis()
        val response = chain.proceed(request)

        AlibabaCloudRumUtil.requestCost(
            source,
            snapshots = url,
            System.currentTimeMillis() - startTime
        )

        // 判断是否是 HTTP 错误
        if (!response.isSuccessful) {
            AlibabaCloudRumUtil.requestFail(
                source,
                snapshots = url,
                params = AlibabaCloudRumUtil.errorMap(
                    response.code.toString(),
                    response.message
                )
            )
        } else {
            val source = response.body?.source()
            source?.request(Long.MAX_VALUE)
            try {
                val buffer = source?.buffer
                // 业务错误逻辑上报
                val result = gson.fromJson(
                    buffer?.clone()?.readString(Charset.forName("UTF-8")),
                    BaseModel::class.java
                )
                if (result?.code != 0) {
                    AlibabaCloudRumUtil.requestFail(
                        ACRSource.COROUTINE,
                        snapshots = url,
                        params = ResultException(
                            "${result.code}",
                            result?.message ?: "Unknown error"
                        ).toMap()
                    )
                }
            } catch (ex: Exception) {
                AlibabaCloudRumUtil.requestFail(
                    ACRSource.COROUTINE,
                    snapshots = url,
                    params = BusinessException.handlerException(ex).toMap()
                )
            } finally {
                source?.close()
            }
        }

        return response
    }
}

网络请求上报是带上了URL,现在的Retrofit 的URL 在其他地方是真的不好拿,这 Interceptor 确实方便的很。
而网络耗时也比较容易,在
val response = chain.proceed(request)
前后记录时间就可以了,虽然跟抓包数据显示的网络耗时有差距,但是我们毕竟只是粗略的统计而已。
错误上报的话,包括了 http 请求错误和 code != 0 的业务数据错误,都是需要上报的。

如果需要在其他地方拿到 URL ,需要在 Interceptor 里处理,重新 new 一个 Response 返回,然后把 URL 塞到 Header 里面,在其他地方把 Header 中的 URL 读取出来。但是会产生一点性能开销,毕竟每个请求都需要 new 一个新的 Response 。


http://www.kler.cn/a/305479.html

相关文章:

  • Python 小高考篇(2)字符串
  • Nebula NGQL语言的使用 一
  • 软件设计师-信息安全
  • 高性能分布式缓存Redis-高可用部署
  • 《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>
  • Android CarrierConfig 参数项和正则匹配逻辑
  • 「OC」事件点击demo合集
  • python数据分析知识点大全
  • 560 和为k的子数组
  • pptp解说
  • vb.net发送邮件:如何高效地实现邮件发送?
  • 【鸿蒙】HarmonyOS NEXT星河入门到实战4-ArkTS界面布局深入
  • 什么品牌的宠物空气净化器性价比最高?352/希喂/霍尼韦尔/有哈/IAM实测对比
  • Oracle(125)如何执行不完全恢复?
  • Netty笔记07-粘包与半包(上)
  • 新能源汽车出海中的数据合规热点问题
  • 系统分析师--系统可靠性分析与设计
  • Rust编写Windows服务
  • 从“天宫课堂”到人工智能:中国少儿编程的未来在哪里?
  • golang学习笔记12——Go 语言内存管理详解
  • 软件测试工程师面试整理-数据库与SQL
  • 微信小程序使用 ==== 粘性布局
  • Ubuntu 常用指令和作用解析
  • 16. MyBatis的延迟加载机制是什么?如何配置?有哪些优缺点?
  • 股票程序化交易赚钱吗,证监会如何监测股票多账户关联交易
  • Vue 创建自定义指令 以及创建自定义指令相关属性说明