什么是埋点
- 所谓“埋点”,是数据采集领域(尤其是用户行为数据采集领域)的术语,指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。
- 帮助定义和获取分析人员真正需要的业务数据及其附带信息。
- 在应用中特定的流程里收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑,包括访问(Visits),访客(Visitor),停留时间(Time On Site),页面查看(Page Views,又称为页面浏览)和跳出率(Bounce Rate,又可称为蹦失率)。
- 这样的信息收集可以大致分为两种:页面统计(track this virtual page view),统计操作行为(track this button by an event)。
常用术语
- PV(Page View):页面浏览量或者点击量:某个用户某次对网站中的某个网页进行访问,就记录一次PV。
- UV(Unique Visitor):通过互联网访问、浏览这个网页的自然人。访问网站的一台客户端为一个访客,0:00-24:00内相同的客户端只被计算一次。一天内同一个访客多次访问仅计算一个UV
埋点的方式
- 在产品开发中注入代码,并搭建起相应的后台查询
- 使用三方统计工具,如友盟、百度移动、魔方、App Annie、talking data等。如果你的数据来自第三方,那你使用的工具也应该是第三方统计工具,后续没啥数据产品了。
公司Hybird App里的Web项目埋点经验
业务场景
- 在App里某业务线嵌入的Web项目
- 埋点和BI部门对接
- 没有使用第三方平台
js-base64
- Base64是基于64个可打印字符来表示二进制数据的表示方法。
- 用处往往并不是为了防止信息泄露,而且为了方便传输,进过Base64编码后的信息会比原始信息长,每6个比特为一个单元,对应某个可打印字符。而3个字节占用24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示,所以长度大概是4/3倍。
- 其源码里包含
- key:一个String字符串,长度为64
- encode方法:加密算法;
- decode方法:解密算法;
使用方法很简单
1
npm i --save js-base64
1
2
3
4import { Base64 } from 'js-base64'
var result = Base64.encode(str)
var result2 = Base64.decode(result)
protobufjs
- 现在HTTP通信我们一般采用JSON格式,这次公司的BI采用了不一样的数据传输格式。
- Protocol Buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。采用类似TLV(tag,length,value)的编码方式,输出一段字节数组,是一种二进制格式的协议。它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++、JAVA、Python等三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。
数据体积方面的优势是比较明显的。JSON文件的问题在于无效数据太多(这里指每传一个对象就有一套键值对,键名都是重复的),这些内容大量重复出现,使得数据体积较大。而protobuf文件,它使用一个唯一的id(数字)来代替JSON里复杂的key,这样只要数据发送方和接受方都按约定的同一套“模板”来解析数据,就可以大大缩短报文体积。
1
2
3
4[
{"Name": "zhangsan", "Gender": 0, "Age": 18},
{"Name": "lisi", "Gender": 1, "Age": 19}
]1
2
3
4
5message Person {
required string Name = 1;
optional int32 Gender = 2;
optional int32 Age = 3;
}protobufjs是基于ByteBuffer.js的Protocol Buffers的纯Javascript实现。主要功能是解析
.proto
文件,构建message类,和进行简单的编码、解码。- protobufjs依赖包了解一下,网络世界中的数据传输从一开始的XML到JSON现在越来越多的人开始向protobuf转变
- 简单的说,protobufjs发挥的作用就是protobuf数据和js对象的相互转换
使用方式:(前端模版用JSON)
首先要定义好一个json模版
1
2
3
4
5
6
7
8
9
10
11
12
13// awesome.json
{
"nested": {
"AwesomeMessage": { // 怎么定位?下面就会看到
"fields": {
"awesomeField": {
"type": "string", // 类型要求
"id": 1 // 就是用这种id来替代key
}
}
}
}
}JSON的结构,粗体标识的是必须的:
| type (t) | extends | type-specific properties
|:—:|:—:|:—:|
| ReflectionObject | | options
| Namespace | ReflectionObject| nested
| Root | Namespace | nested
| Type | Namespace | fields
| Enum | ReflectionObject| values
| Field | ReflectionObject| rule, type, id
| MapField | Field | keyType
| OneOf | ReflectionObject| oneof (array of field names)
| Service | Namespace | methods
| Method | ReflectionObject|type, requestType, responseType, requestStream, responseStream
JSON文件可以被load也可以以模块的规范来引用,比如
1
2var jsonDescriptor = require("./awesome.json"); // exmplary for node
var root = protobuf.Root.fromJSON(jsonDescriptor)使用可以有多种方式,用js api的方式,根据官方提供的:
1
2
3
4
5
6
7const AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage"); // 定位
let message = AwesomeMessage.create({ awesomeField: "hello" }); // 传入参数,根据上面定位的模版生成
console.log(`message = ${JSON.stringify(message)}`);
let buffer = AwesomeMessage.encode(message).finish(); // encode刚才生成的东西,这个就可以作为data发给后端了
console.log(`buffer = ${Array.prototype.toString.call(buffer)}`);
let decoded = AwesomeMessage.decode(buffer);
console.log(`decoded = ${JSON.stringify(decoded)}`);