现状和问题

闲鱼的舆情治理,依托阿里集团的设施建设,具备以下能力:
崩溃异常、性能在线聚合查询;
本地日志:TLog;
在线日志:埋点日志(t+1)和用户行为日志(路径和请求)
但在应对舆情治理方面仍存在较多的问题:
有相当一部分闪退、黑屏、卡死舆情无Crash或ANR日志;
技术舆情中的业务问题定位困难;
日志内容缺失:大部分业务日志被写入控制台,而不是本地日志或在线日志;
个别重要业务使用埋点日志,但仍可能存在内容不足和t+1不及时问题。
本地日志定位问题能力有限
本地TLog日志有较为详细的集团二方SDK日志,但缺失设备基础信息、业务日志、用户行为日志等
日志规范不完善,日志查看效率低
本地日志回捞困难
闲鱼属于交易App,用户不会长时间在线,在线命令推送成功率低
命令推送在后台没有缓存机制
舆情治理方案整体设计基于现状问题,重新梳理和补充的舆情治理体系如下图:

下面会重点展开讲述的内容:
如何提升本地日志定位能力
补充线上卡顿监测能力
补充主动发现问题能力
提升本地日志定位能力本地控制台日志补充AndroidLog模块提供了多种日志缓存类型,见Androidlogging[1],可通过logcatLOG_ID_MAIN、LOG_ID_EVENTS和LOG_ID_CRASH类型logcat读取并写入到本地文件,而后将logcat日志同tlog文件一起打包通过AUS上传至OSS。
//LOG_ID_MAIN主应用程序log,-t设置日志上限20000
adblogcat-d-vthreadtime-t20000
//LOG_ID_EVENTS系统事件信息
adblogcat-d-bevents-vthreadtime-t6666
//LOG_ID_CRASH应用程序crash日志
adblogcat-d-bcrash-vthreadtime-t6666

前面提到,由于在线命令推送成功率低且后台无命令缓存机制,所以闲鱼App本地日志回捞困难。为解决日志难以获取问题,舆情治理体系中设计了多种日志回捞策略,见下图所示。


为提升研发下载本地日志的效率,使用TLogSDK上传至TLog平台,其中50%以上能上传成功。
线上卡顿/ANR检测能力
在闲鱼App的混合工程场景,依托Emas平台已实现iOS端卡顿检测,Flutter端卡顿检测方案查看Flutter卡顿问题的监控与思考[2],这节主要讲述Android端线上卡顿/ANR检测。
在线下场景,Android端卡顿/ANR检测手段已经很成熟,普通卡顿检测方案有BlockCanary[3],ANR检测可通过adbbugreport查看文件得到。然而在线上环境,以上卡顿检测方案就存在一定问题。
文件权限问题在线上场景,为了监听识别是否发生ANR以及读取ANR内容,APP需要监听文件变化,并尝试读取文件内容。监听文件的方案,在及以后存在权限问题,大部分场景无法检测到ANR
无法访问/data/anr/文件
无法读取有效系统属性
如以下代码执行在红米手机Android11上运行,mSystemTraceFilePath为"",mSystemTraceFile的路径为"/"
FilemSystemTraceFile;BlockCanary检测原理和性能问题核心原理
="/data/anr/";
=newFile();
if(!()){
StringpropSystemTraceFilePath=("");
=newFile(propSystemTraceFilePath);
}

BlockCanary的核心原理是,设置UI线程的字段,主线程每次处理消息均会执行print方法。
publicvoidstart(){
if(!mMonitorStarted){
mMonitorStarted=true;
().setMessageLogging();
}
}
publicvoidsetMessageLogging(@ablePrinterprinter){
mLogging=printer;
}
publicstaticvoidloop(){
for(;;){
//Thismustbeinalocalvariable,incaseaUIeventsetsthelogger
finalPrinterlogging=;
if(logging!=){
("Dispatchingto"++""+
+":"+);
}
}
}
在print方法中时,触发StackSampler工作,即取消上一次异步线程延迟任务,重新触发一次延迟任务,延迟时间为BlockThreshold*0.8f(假设要检测500ms以上的卡顿堆栈,则延迟时间为400ms)。若UILooper任务发生卡顿(BlockThreshold),则延迟任务被执行,且在卡顿期间的获取主线程堆栈信息,之后在下一次print方法被执行的时候,若确认发生卡顿,则可把主线程堆栈信息当做卡顿堆栈记录上报。
@Override性能问题
publicvoidprintln(Stringx){
if(!mPrintingStarted){
mStartTimestamp=();
mStartThreadTimestamp=();
mPrintingStarted=true;
startDump();
}else{
finallongTime=();
mPrintingStarted=false;
if(isBlock(Time)){
notifyBlockEvent(Time);
}
stopDump();
}
}
在线上环境,大部分场景下并不会发生卡顿,但卡顿检测SDK会一直执行。可以发现app每一帧时间(16.6ms),UILooper中的任务会执行多次,最终产生大量的无效字符串拼接操作和大量小对象碎片。特别的,在线上低端机或者cpu负载较高的场景下,app性能会因此降低,影响用户体感。
("Dispatchingto"++""+
+":"+);
卡顿检测方案方案设计针对读取权限问题,可通过检测主线程5s卡顿当做anr。针对BlockCanary线上使用的性能问题,为降低延迟任务取消和触发频率,同时避免字符串对象频繁创建问题,必须放弃的方案。重新思考为什么可以通过设置检测卡顿?其满足2个条件:
若主线程方法执行发生卡顿,则LooperTask执行时长变长
可通过监听每个Task执行时长
闲鱼线上使用Android帧回调代替LooperTask方案,同时满足以上2个条件:
若主线程方法执行发生卡顿,则帧回调间隔时长变长
可通过注册帧回调监听每帧时长
此外,为避免BlockCanary方案延迟任务触发和取消的频率过高的问题,仅在帧回调处记录时间戳,不再取消延迟任务,但在延迟任务执行时判断是否发生卡顿,同时记录主线程堆栈。
假设500ms以上为卡顿,整体方案流程图如下:
无卡顿场景

卡顿场景

仅在频繁触发的帧回调处,记录时间戳,无性能消耗
避免延迟任务触发和取消的频率过高的问题,500ms(卡顿阈值)最多执行2次延迟任务
不再取消延迟任务
在任务执行时,判断当前时间和上一帧时间戳时间差。仅在发生卡顿时,dump主线程堆栈
定义5s以上卡顿为ANR,为检测ANR,同样通过500ms卡顿检测,并做卡顿堆栈聚合,当连续发生卡顿大于5s且堆栈信息不变,则认为发生ANR。发生ANR时,记录当前设备CPU负载等信息。
检测效果//
privatevoiddoOnClick(StringredirectUrl,MapString,StringtrackParams){
if(==mCardBean)return;
try{
(500);
//(5000);
}catch(Exceptione){
();
}
}
查看检测结果
Sleep500ms

Sleep5s

线上卡顿检测无性能问题
以5s以上卡顿当做ANR
相比BlockCanaryLooperTask在0.8*卡顿阈值时获取卡顿堆栈,本方案500ms卡顿检测有更高概率获取错误堆栈。但通过连续卡顿堆栈比对,可确保5s卡顿堆栈的准确性。而500ms卡顿通过线上统计提升准确性
若业务需要,必须提升500ms单次卡顿堆栈准确率,可简单修改方案:判断大于250ms获取一次卡顿堆栈,2次连续相同卡顿堆栈且卡顿时长大于500ms作为最终卡顿判断
主动发现问题能力

业务舆情问题大盘
通过统计一段时间的舆情问题,得到关键舆情问题,以此添加监控埋点并构建线上报表。通过大盘数据得到线上问题发生量和重要归因,通过重点解决排名前几的归因,达到舆情问题快速收敛的目的。
基础问题
除了Crash、Flutter异常、性能等线上大盘,我们构建了5s卡顿监控、网络请求失败、慢请求、错误toast等基础监控大盘。
监控问题定位实时日志查询平台
针对关键监控问题,客户端增加对应的SLS实时日志,在自建舆情追踪平台获取用户的在线日志。平台支持用户名和时间查询,同时支持用户行为、用户异常、舆情日志类型的组合查询。
本地日志批量回捞能力在线日志难以避免日志内容不足的问题,如基础日志、其他关键模块日志等,然而单个用户的本地日志回捞成功很低(原因见上文内容),为此构建舆情日志回捞平台,通过批量回捞的方式确保能获取到舆情问题某个用户的本地全量日志。
输入舆情IssueName查询用户id


批量回捞结果查询

经过治理,整体线上技术类舆情占比从10.5%降低至4.7%;基于主动发现问题和解决重点问题,每日上传图片失败数从10W+次降低至小于7K+次,其他数据不再罗列。
初步建立的闲鱼舆情治理体系如下所示:
日志类型:本地日志和在线日志;
在线日志:实时在线SLS日志,用户行为日志,埋点(t+1)日志,高可用SDK日志(崩溃异常、白屏、性能);
日志查询:提供日志规范和日志过滤文档提供查询效率;
日志内容:基础日志和业务日志;
基础日志:logcat日志,卡顿/ANR日志,高可用SDK日志(crash、异常等),设备信息、账号信息等;
此外,未来仍有很大的演进空间如下:
日志可视化
日志语义化描述展示
用户行为、内存、CPU、流量等可视化

日志智能解析
关键日志和历史问题关联形成知识库
关键日志反向回捞用户日志
类似主动发现问题场景中的回捞能力,可根据配置下发或其他关键在线日志回捞用户日志
日志关联聚合查询
基于用户和时间,聚合服务端、前端、客户端日志,聚合多种在线和本地日志。
References[1]Androidlogging:
[2]Flutter卡顿问题的监控与思考:
[3]BlockCanary:
[4]:
[5]:
闲不住?来闲鱼!
PICKME
闲鱼是阿里巴巴旗下品牌,是中国最大的闲置交易平台,于2014年成立至今,是继淘宝、天猫之后,阿里巴巴正在催生的第三个万亿级平台。
闲鱼技术部不断在驱动业务变革,通过创新追寻更多价值。从出版书籍、峰会发声,到开源专利、海外传播。闲不住,上闲鱼——技术团队对极致的探索与深耕是我们的底气。
立即加入
1、社招+校招客户端/服务端/前端/数据+算法/质量工程师
2、发简历给@