当前提到APP统计,友盟无疑是做得最好的一家,同样类型的公司有talkingData,CNZZ(参考 app统计工具简单介绍),此外百度,AVOS等也提供了类似的服务,但是有的时候公司不愿意APP相关数据外漏,希望对于一些日志数据进行自行处理,就需要自己搭建统计平台。
Countly是国外比价有名的一款开源统计平台,Countly的历史和相关信息参考网页 Countly如是说,其包括一个node.js的server,以及Android,IOS,JS,WP和Unity的客户端SDK,并且是以实时的方式进行统计。
countly平台的简单使用可参考博客:http://blog.csdn.net/changemyself/article/details/12653151
由于我们要做的相对简单,不需要复杂的功能,因此我没有采用Countly自带的server,而是自己写了一个统计脚本(主要是没有设备去配置node.js和mongoDB,而且部分数据得和另外一个系统对接),对于数据进行入库和每日的统计。
基于Countly的统计平台结构
整体结构
Countly Service Management(客户端):
使框架拥有通用性,不同APP可以使用同一个SDK,Countly Service Management提供一个Android后台Service管理队列,给每个APP和其启动的Service通过Tag对应上,负责顺序唤醒当前APP对应的Service,并通过使用频率调整管理队列。
Countly Framework(客户端):
APP统计数据的处理核心,Countly提供一个全局实例和APP里的初始化方法,同时维护EventQueue和ConnectionQueue两个事件队列。其中EventQueue维护自定义(如激活,埋点,出错)事件的记录和发送,ConnectionQueue维护APP的打开,关闭,停留时间计算等常规数据记录。
Countly通过Timer将两个Queue中的数据定时发往Server。EventQueue和ConnectionQueue同时带有本地存储功能(无需SD卡),在网络发送成功时清除本地SharedPreference记录数据。
上传时使用Post方法,每次批量上传全部记录。如果上传不成功(网络异常),则本地缓存记录数据超过一定数量(100)后,会清除较早的一半数据。
Countly Web Interface(Server端):
测试阶段用Python搭建了简单服务器,处理Post请求。postHandler将请求数据传递给解析脚本,将数据转义、分割并解析成python dict,然后区分不同类型的数据,将数据插入轻云中的Mysql中。
客户端SDK结构
客户端数据记录类型
由客户端发往服务器的主要有4中记录类型,他们都是转码之后打包成json格式,混在一起发送到服务器的。
类型 | 说明 | 类型id |
---|---|---|
BeginSession | 登入APP | 100 |
UpdateSession | 更新登入的时间 | 101 |
EndSession | 登出APP | 102 |
Events | 自定义事件 | 103 |
其中,beginSession表示一个打开APP的动作,仅记录一个开始时间,之后每隔一个时间间隔(例如30秒),则会再生成一条updateSession,表示持续时间增加多少,这样可以较精确地实时指导用户在线情况和实际使用时间,当用户退出前会产生一个endSession,表示一个用户ID从BeginSession到UpdateSession,到EndSession生命周期结束了,服务器可以做这一个周期的统计工作了。
Event则是自己定义的,原则上打开APP,不如不出发代码总发送事件的部分,是只有前三种生命周期记录的。Event就是让你在代码中为你要统计的各种事件埋点的。
这些记录在Countly SDK中的格式如下,下篇文章会就源码实现来仔细记录。
BeginSession信息描述
Json样例:
{"_locale": "zh_CN", "_os": "Android", "timestamp": "1405421176", "app_key": "XIAOMAI_4S5R7C2D", "_os_version": "4.1.2", "metrics": "1", "sdk_version": "2.0", "_app_version": "1.2.1", "_resolution": "480x854", "_density": "HDPI", "begin_session": "1", "_channel": "1001", "_carrier": "China+Mobile", "_device": "MI+1S", "device_id": "2141724f81a367bc"}
名称 | 值样例 | 说明 |
---|---|---|
timestamp | 1405421227 | 事件时间戳 |
app_key | XIAOMAI_4S5R7C2D | 在客户端和服务器约定的appkey |
device_id | 2141724f81a367bc | 设备udid,可唯一识别设备 |
begin_session | 1 | 表示该记录类型 |
metrics | 1 | 表示该记录带metrics信息 |
Metrics信息
带有metrics的所有信息
字段名称 | 值样例 | 说明 |
---|---|---|
_locale | zh_CN | 区域信息 |
_os | Android | 系统类型 |
_os_version | 4.1.2 | 系统版本号 |
sdk_version | 2.0 | 统计sdk版本号 |
_app_version | 1.2.1 | App版本号 |
_resolution | 480x854 | 屏幕分辨率 |
_density | HDPI | 屏幕分辨度 |
_channel | 1001 | App来源渠道码 |
_carrier | China+Mobile | 运营商 |
_device | MI+1S | 手机类型(品牌) |
UpdateSession信息描述
Json样例:{"timestamp": "1405421327", "session_duration": "20", "app_key": "XIAOMAI_4S5R7C2D", "device_id": "2141724f81a367bc"}
名称 | 值样例 | 说明 |
---|---|---|
timestamp | 1405421227 | 事件时间戳 |
app_key | XIAOMAI_4S5R7C2D | 在客户端和服务器约定的appkey |
device_id | 2141724f81a367bc | 设备udid,可唯一识别设备 |
session_duration | 13 | 停留时间增量(秒) |
EndSession信息描述
Json样例:{"timestamp": "1405499182", "session_duration": "1", "end_session": "1", "app_key": "XIAOMAI_4S5R7C2D", "device_id": "2141724f81a367bc"}
名称 | 值样例 | 说明 |
---|---|---|
timestamp | 1405421227 | 事件时间戳 |
app_key | XIAOMAI_4S5R7C2D | 在客户端和服务器约定的appkey |
device_id | 2141724f81a367bc | 设备udid,可唯一识别设备 |
end_session | 1 | 标识该记录为登出 |
session_duration | 13 | 停留时间增量(秒) |
Events信息描述
Json样例:{"timestamp": "1405421187", "events": [{"count": 1, "timestamp": 1405421176, "sum": 0, "key": "open_acivity"}], "app_key": "XIAOMAI_4S5R7C2D", "device_id": "2141724f81a367bc"}
发送来的一条记录中可能有多条event,需要进行分离
名称 | 值样例 | 说明 |
---|---|---|
timestamp | 1405421227 | 记录时间戳 |
app_key | XIAOMAI_4S5R7C2D | 在客户端和服务器约定的appkey |
device_id | 2141724f81a367bc | 设备udid,可唯一识别设备 |
Events | 1 | 标识该记录为自定义事件 |
key | open_acivity | 该事件的标识 |
count | 1 | 事件出现次数 |
sum | 10 | 一个累加值,可自行使用 |
timestamp | 1405421176 | 事件发生的时间戳 |
好了,以上介绍了我开发的基于Countly的统计的主要架构和其记录的表示含义。下一篇将根据源码分析Countly Android SDK的运行机制。
文章为原创,转载请注明出处。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。