1、基于Proxy的代码执行监听上报l 需求背景l 玩转Proxyl API上下文l 应用场景目录需求背景日志是程序监控和问题排查常规和重要手段打日志繁琐:1.SDK实现中需要打日志2.业务代码调用SDK需要打日志能否统一处理?代码更少,更规范!线性无关联只能体现时序可视化展示体现上下文图片、视频对应客户端组件属性变化也要追踪API依赖上报上报MethodMethodProperty递归上报同步结果回调与参数调用上报业务代码在不改变SDK代码的情况下做到get、set上报1.统一上报入口Property.2.属性get、set上报3.API结果、回调上报4.日志体现API依赖SDK客户端3、4可统
2、称上下文关系玩转Proxy分析文档 收集API definePro可视化展示 分析处理 收集上最初方案definePropertydefineProperty1.只能监听已有属性2.无法追踪新增属性此方案的问题:1.文档上API只是公开出去的2.API会不断新增3.开发者改动Proxy是ES6新增语法在目标对象前架设一层拦截,可以对外界的所有访问进行过滤和改写做你想做ProxyTarget利用Proxy可以1.监听属性get、set2.函数包装监听API调用在不修改源码的情况下做到1.统一上报2.使用者也能监听API调用整理文档 收集API Proxy代可视化展示 分析处理 收集上改进方案Pr
3、oxy用Proxy对象替换原对象需要考虑下面两个问题:1.能否替代原对象2.Proxy性能代理对象同原对象原型一致、类型一致代理对象和原对象属性相同代理DOM对象后使用报错利用空对象做中转:1.属性get取原DOM对象属性2.属性set设置原DOM对象属性3.代理对象的原型设为原DOM对象原型解决DOM对象直接代理使用报错的问题代理对象与原对象有同样的原型,同样的属性可以认为在使用上等同于原对象类别代码let tmp = test.index 0ms/万次 mstarget-gettarget-settarget-call0056test.index = 1test.func(1)0138pr
4、oxy-get let tmp = proxy.index 163186331968proxy-setproxy-callproxy.index = 1proxy.func(1)31let tmp =defineProperty.indexdefineProperty-get1327defineProperty-set defineProperty.index = 1 2defineProperty-call defineProperty.func(1) 112312421性能对比不是高频调用,性能影响可忽略实践中性能影响大的是上报可控制上报频率,如:1.缓存一定数目再上报2.黑名单内API不
5、上报3.同一个API限制一定时间内上报次数4.同一属性get、set,同值只报一次API上下文上下文需关联如下关系:1.API调用2.API回调函数3.回调参数(API结果)使用4.回调中其他API调用通过根API将整个上下文关联起来API包装函数产生ID回调函数包装函数可知所属API关联API和其回调函数包装函数碰到下面两个问题:1.构造函数2.事件监听构造函数作为方法调用产生空对象比对原型判断是否作为构造函数调用判断作为构造函数使用的情况事件监听,利用缓存,避免监听与取消监听函数不一致的情况参数若为对象,继续代理,关联回调函数获得当前执行函数和外层函数:1.利用callee可以知道当前执行
6、函数2.利用caller可以知道当前执行函数外层函数关联回调函数和回调函数中API严格语法中callee、caller被禁止利用栈关联当前函数和外层函数:1.回调函数的包装函数运行时生成ID2.回调函数ID执行前入栈,执行后出栈3.函数运行时通过栈尾ID可知其上层函数关联回调函数和回调函数中API执行顺序调用栈(数组)关联映射(map)上下文(根id)api1sync:1api1sync:cbk:2api2async:3api1sync:cbk:223api4sync:4api4sync:cbk:5api4sync:cbk:55api2async:cbk:6 api2async:cbk:6ap
7、i3sync:767异步顺序调用栈(数组)api1sync:1关联映射(map)上下文(根id)api1sync:1api1sync:cbk:2api1sync:cbk:2234setTimeout:3api2async:4setTimeoutapi2async:4setTimeout:cbk:5 setTimeout:cbk:5api3sync:6 api3sync:656应用场景Zipkin是一个开源的分布式链路追踪系统可用来做日志关联和可视化展示有traceId、id、parentId即可用zipkin做日志关联和可视化展示没有源码的情况下通过上下文日志回溯调用过程简化部分API测试案例整理API 运行代码 收集分析日触发CI跑测试案例 代码变更 生成测试案对于有固定输入输出的API,可自动生成测试案例。日志可分析出上下文,可以构造含一定业务逻辑的复合API的测试案例其他场景API调用统计丰富测试案例总结1.Proxy追踪属性变化和方法调用2.集中上报,SDK使用者也能使用3.通过函数包装关联API和回调函数4.利用栈关联回调函数和回调函数中其他API5.日志从线性变为有关联关系的上下文6.借助全链路系统可视化展示,回溯调用过程7.可应用到API统计和测试