金服平台数据分析系统各类日志数据采集系统总体方案修订记录日期修订版本修改描述作者2017-04-290.5.0开始写金服平台数据分析系统各类日志数据采集方案2017-05-90.7.0初步完成移动和Web页面非实时日志采用Countly实现日志采集与收集实现方案2017-05-180.8.0补充移动和Web页面实时日志采集部分内容2017-05-220.8.5初步设计拦截器实现移动和Web页面后端实时日志采集构架1.金服平台移动App日志内容要求规范1.1日志系统需收集更多数据时移动应用采用埋点上传日志技术与App日志上传暂行规定很早之前,也就是当年的PC时代,由于受限于存储和计算能力,大家一般很少用日志来分析业务。而是在业务逻辑里,将业务需要分析的数据事先写入到库里,针对库的数据进行统计分析。所以之前做OLAP,需要很高级的硬件支持,大家都去IOE等买昂贵的服务器来做数据仓库以及进行数据分析。由于成本的问题,拿到的数据是很少的,所以进行统计分析和挖掘所得到的收益微乎其微。随着Hadoop的兴起,分布式文件系统和分布式计算大大降低了存储成本和计算成本,使得现在用日志分析业务成为了可能。1.1.1移动App分析的数据类型对于移动端的App来说,分析的数据大致上都可以分为俩种,一种是在线数据,一种是离线数据,还有App业务需要的综合动态数据(简称动态数据)。1.1.1.1在线数据在线数据,即App后端服务所产生的日志数据,例如服务接口的性能数据,服务接口的调用及其参数等,通过服务端的日志数据,我们不但可以统计服务接口的性能指标,还可以针对具体的业务逻辑,做相关的分析,一些常见的App分析指标如新增,活跃,累计,留存等,也都可以通过服务日志来统计出来。因为App嵌入了移动Web的Html5页面,故App的在线数据包含了App原生应用后端服务接口性能数据和移动Web日志数据。1.1.1.2离线数据对应的离线数据即是App客户端本身产生的数据,这种情况一般是发生在客户端不调用底层服务的情况下,需要了解用户在客户端的行为,就需要用到离线数据。离线日志一般记录用户在客户端的具体行为,如用户在客户端的拖动,上下滚动,翻页等不涉及到后端服务的操作,以及App本身的崩溃行为产生的数据,都可以被记录,一般的,记录的内容包括事件类型,控件编号,控件属性及相关参数,事件时间等。因为Html5提供离线功能应用,故这里的离线数据也要考虑离线状态下Html5前端产生或者使用的数据。对于离线数据还要考虑原生与Html5混搭Hybrid接口上原生到JS和JS到原生的数据调用情况。1.1.1.3动态数据针对App,为了统计和分析服务成功率、服务耗时、连接成功率和连接耗时等性能和质量,新增加除了上述在线数据和离线数据的第三种类型数据,暂时命名为综合动态数据(简称动态数据),一个(综合)动态数据内容主要记录了用户开始操作一个App界面元素、发送Http请求、接收对应的Http响应、界面展现等时间点、过程中内存流量和处理失败原因,对(综合)动态数据和与之关联的在线数据进行关联分析,可以统计出服务成功率、服务耗时、连接成功率和连接耗时等性能和质量数据。1.1.2在线日志在线日志,一般来讲,有两种:web服务器的配置化log(如Nginx,apache等web服务器的access.log)这一类日志不需要用户自己做实现,只需要开启web服务器的相关日志功能,即可完成日志记录。应用服务器的log一般包括应用服务器的配置化log以及用户自定义的log。用户自定义log包括用户通过相关日志组件自己的debug,waring,error,info等级别的日志。这一类日志没有固定的格式,完全有用户自行控制。在线日志一般会伴随业务直接产生在相关的业务服务器上(web服务器日志产生在web服务器上),但是有的时候,为了将相关服务的监控日志与业务分析日志分离,会将业务日志直接记录在一台独立的日志服务器上。这里,App的在线日志主要包含上述1.1.1章节涉及的在线数据类型包含的App原生应用后端服务接口性能数据日志和Html5移动后端Web日志。1.1.3离线日志离线日志(和离线数据有关的),一般也有两种:客户端的(本地)行为日志:用户在操作App的时候(客户端不调用底层服务的情况下)产生的行为,都可以记录下来。行为日志一般是用来研究用户使用习惯,分析应用的使用热度的。同时可以结合客户端异常日志来分析异常原因。客户端的(本地)异常日志:用来监控客户端异常原因,帮助解决相关问题。针对App的离线日志除了涉及到App客户端行为日志与异常日志,还要包含Html5离线状态数据日志和Hybrid接口数据日志。1.1.4(综合)动态日志(综合)动态日志是针对App统计和分析服务成功率、服务耗时、连接成功率和连接耗时等性能和质量新增加的日志,该日志数据类型是上述1.1.1章节涉及的(综合)动态数据。1.1.5埋点及上传不管是在线日志,还是离线日志,或者(综合)动态日志,首先都要确认在什么地方记录日志,于是就引入了埋点的概念。通俗的讲,在正常业务代码逻辑上,添加记录日志的代码,都叫做埋点。但是一般的,埋点只用来描述客户端日志记录。由于在线日志是直接产生在服务器端,日志采集工具可以直接从含有日志的服务器上采集日志数据到相应的文件系统,所以不存在日志上传的问题。但是对于离线日志和(综合)动态日志来说,数据是产生在App客户端的,所以上传机制必须考虑。1.1.6离线日志和动态日志上传机制业界采用的离线日志上传机制如下:①服务端提供日志记录接口,当客户端有事件时,直接调用日志记录接口将日志记录在服务器端。②服务端提供日志上传接口,客户端先将日志暂存客户端本地,当达到一定的大小,网络环境允许的情况下,通过上传接口,将日志文件打包压缩后上传。第一种上传方式,时效性方面有一定的保障,在网络环境允许的情况下,能及时的将信息记录到服务器,但是当埋点较多时,记录日志产生的流量会很大,占据很大的带宽,给用户带来损失。同时,前端的某些行为,如在某个activity停留时间等也无法通过这种在线的方式捕获。还有一个重要的问题是,由于客户端数据没有暂存机制,当网络暂时无法使用时,日志记录接口无法正常调用,所有的日志也就随之丢失。第二种方式,在时效性上较差,因为它需要等待数据累计到一定程度,或者网络允许的情况下,如在wifi情况下,才发送,但是占用的带宽相对较小,对客户端动作的捕获较为灵活。对于的离线日志和(综合)动态日志,建议采用第二种日志上传方式。App的实时日志和PC-web的页面实时日志在后台的Action或者Controller上处理,详细参见3.2移动App和Web的实时业务日志采集方案。1.1.7埋点的三种方案1.1.7.1传统埋点:开发者直接在客户端埋点。优点:开发者可以随意的在任何地方添加埋点。缺点:成本高,每次埋点的增删改都需要发版,很难控制。启明星现在采用的就是传统的埋点方式,由于之前没有统一的规划,相关页面的同一个按钮,不同的版本功能不同,但却埋了同一个点,造成统计比较混乱。之后引入了埋点下发平台,虽然一定程度上缓解了这种问题,但是由于其灵活性以及主观性,问题依然无法避免。1.1.7.2可视化埋点由于传统埋点的一系列问题,自然而然的就产生了可视化埋点的方案,用可视化交互的手段来代替写代码,将核心代码和配置,资源分开,在App启动时通过网络更新配置和资源来实现埋点功能。可视化埋点的大体流程如下:首先埋点服务平台与埋点客户机做关联,包括客户机包含的埋点模块扫描当前整个客户端页面的控件,形成控件树,并将当前页面截图,发送给埋点服务端平台;埋点服务端平台接收到截图和控件树数据后,在服务端重新绘制App界面,通过可视化交互的方式,给当前页面需要埋点的控件上添加事件,添加完毕后,形成配置文件,并发布上线;装有埋点模块的所有客户端,接收到配置文件并解析,根据配置为页面中相关的控件添加监听事件,当这些控件出发事件时记录日志。其中有很多细节的地方需要注意:可视化埋点也需要考虑不同版本之间埋点的差异;可视化埋点在分发埋点配置文件的时候,会有延迟或者丢失的情况,有的客户端有可能收不到或者很久才能收到配置文件,这样埋点的时效性会大打折扣。1.1.7.3无埋点所谓的无埋点,其实也就是全埋点,它和可视化埋点很像,可视化埋点是根据埋点配置来收集数据,而无埋点方案则是尽可能的收集所有控件的操作数据。实现原理也很简单,客户端添加扫描代码,为每个扫描到的控件添加监听事件。当事件被触发后,记录日志。其实,大家对此也不陌生,比如很早之前,对PC站点的统计,各大分析平台,都需要在网页head/head之间添加一段js代码。其实那段js代码,就是现在提到的无埋点的扫描代码。这里强调一下,由于可视化埋点是在需要的时候才埋点,所以它并不能回溯事件,也就是说,只能统计需求提出后,埋点开始的所有的数据,埋点之前的数据是拿不到的。而无埋点方案,在开始埋点的时候,所有的数据已经都被记录了,所以它可以查看之前的数据(这里的之前也是相对与提统计需求的时间,而不是相对于埋点的时间),也就是说它可以做回溯。而这种回溯是建立在大量存储要求的基础上的。App暂行采用传统埋点方案。1.2移动App日志内容参考格式(具体根据需求确定)1.2.2App客户端离线日志内容格式(参考或草拟)当前字段有(参考阿里巴巴移动数据日志分析数据字段):字段名类型注释app_idstring当前统一为888888app_namestringapp_id对应的app中文名称app_versionstringapp的应用版本号channelstring应用分发渠道imeistring移动设备国际身份码的缩写imsistring国际移动用户识别码brandstring手机或终端的品牌字段名类型注释device_modelstring手机或终端的机型resolutionstring手机或终端的屏幕分辨率osstring操作系统,如:Android、iPhoneOSos_versionstring操作系统的版本carrierstring移动运营商,如:中国移动、中国联通、中国电信accessstring连接的网络,如:2G、3G、Wi-Fi、4Gaccess_subtypestring网络类型,如:HSPA、EVDO、EDGE、GPRS等network_typestring根据access,acess_subtype转化后的网络类型schoolstring根据client_ip如果为校园网解析出的学校(由服务器分析)client_ipstring客户端ip(是服务端获取到的外网IP,不是app上传的)longitudestring经度,latitudestring纬度,countrystring根据client_ip解析出的国家或地区(由服务器分析)provincestring根据client_ip解析出的省、直辖市、自治区(由服务器分析)citystring根据client_ip解析出的地级市(由服务器分析)districtstring根据client_ip解析出的区、县、县级市(由服务器分析)session_idstring用户的一次会话id,就是tokenreach_timestring到达日志服务器的时间,此时间可作为日志时间直接使用,格式为:字段名类型注释yyyyMMddHHmmss(注意本字段在App上传时为空)event_idstring埋点的事件ID(或者用户行为的标识ID)last_pagestring当前页面来源页(上一页)的页面标题Last_urlstring当前页面来源页(上一页)的页面URL,可以是空start_nowpage_timestring用户最初进入当前页面的时间点(用于计算当前页面的停留时间)now_page_titlestring当前用户离线行为发生时的当前页面now_page_timestring当前用户离线行为发生时的时间