文章背景
面向用户使用的产品,即使项目加入了埋点,某些用户描述的操作场景,也比较难确定实际情况。比如提示对话框,有些页面的数据权限是对话框的展现形式,用户这个时候操作了对话框,进行了页面跳转,是正常的业务逻辑。但是有些情况下,用户跟客服反馈问题时,会有表达上不清晰或者遗漏自己做过的操作等情况。
有些时候,因用户提供的信息不准确,研发在日志系统和埋点系统查找上报数据的时候,犹如大海捞针。为此,产品同事和研发同事共同做了多次操作优化。
但是用户提供信息不准确这种情况是无法完全避免,所以我开始思考别的解决方案。
逆向思维
做了一些正向思维的操作优化,发现还是有用户提出的问题,无法进行快速定位。虽然,已知的业务场景就那几个,但是在日志系统里,很难找到帮助支撑结论的数据。
等等,已知的业务场景,我既然知道了哪些业务场景,为什么不按照这个维度进行数据收集呢?我收集到数据,即使用户提供的信息是错误的,但是场景是真是发生的,我只有找到场景数据,反推用户信息,然后跟用户确实反推出来的信息,不就能解决问题了。
逆向思维,真是解决问题的「良方」之一。
功能设计
上报公共方法
上报方法里主要讲需要上报的数据整理成请求的入参,然后传入日志上报的接口中。
- apiMethod:接口请求方式,有GET和POST两种;
- params:操作场景的主要参数;
- httpApi:如果场景属于异步请求返回值场景,则上报它的api接口相对路径;
- res:如果场景属于异步请求返回值场景,则上报它的响应体;
- describe:场景描述,这个很重要,把用户方操作逻辑描述成文字,方便查询问题时,找到进行过的操作。
/** * 日志上报功能 * @param {Object} data 上报数据 * @return {void} 无 */apiLog(data) { // 接口请求方法constapiMethod=data.method?data.method : 'GET'; // 调用公共上报方法constreqData= { method: apiMethod, // 此接口请求方法params: data.params, // 入参url: data.httpApi, // api接口相对路径 }; // 调用上报接口reportApi(reqData, data.res, data.describe); }
特定业务场景上报
以用户查看订单信息为例。
早上,叶一一刚进入办公室,就看到问题群里信息在闪烁。打开发现客服反馈了一个问题,用户说看不到订单记录。测试的同事正在帮忙筛查问题,测试的同事第一反应是,用户登录的账号不是之前下单的账号。但是用户比较坚持说确定了账号是下单的账号。
测试的同事用提供的账号确实查到了信息,但是研发的同事查登录日志没有查到信息。
此时叶一一打开业务日志的面板,开始筛选操作场景,然后根据用户操作时间,确实了一个大概的操作范围,成功找到几条数据中的账号,该账号和用户提供的信息只有结尾的数字不同。于是叶一一让测试的同事帮忙,让用户确认登录账号是否是家人的账号。果然用户检查了账号后发现登录错了账号。
订单数据为空的时候会上报一条业务数据。
// 日志上报utils.apiLog({ httpApi: '/api/order', params: { accountId: '111', }, res: { userName: '张三', orderList: [], }, describe: '当前订单数据为空,可能原因:1、用户账号没有进行过下单操作,2、用户登录的不是下单账号。', });
总结
依靠这个简单的有点简陋的功能,帮助解决了问题群里60%左右操作问题,大部分因为缺少关键操作描述或者描述信息不准确,而不好排查问题。
实际业务场景比举例中复杂很多,可以根据实际业务场景制定实现策略。
这个功能当时开发主要是为了用极少的开发成本,换取重复问题解决的人力成本,所以功能设计的比较简单。可以根据实际情况,在这个思维上尽情发挥。