很多业务开发觉得自己是做业务,统计监控这些东西,不需要太多深度,本文就说业务开发,如何挖掘统计监控技术深度。
1、统计监控维度
了解一个事物,我们先从广度上来了解,再从深度了解。
按照研发维度,分为2部分
- 平台方,如何研发监控系统
- 业务方,如何接入
- ...
按照业务维度,分为2部分
-
业务监控,如埋点系统
- 业务线的流量分布
- 业务线的转化率
- ...
-
技术监控
- 性能
- 接口请求、业务场景的异常
- js error
- ...
2、研发维度
2.1 平台方
我本人是4年的业务研发,对于如何平台方研发监控系统,理解不深,本文主要想讲的是业务开发如何使用平台方监控功能。这里提供文档资料看一看。
美团点评前端无痕埋点实践
通过日志监控实现日志关键字的监控与报警
从零开始的前端监控之日志采集
UC 百亿级 PV 的前端监控平台实践
如何从0到1搭建前端监控平台
通过这些文档,你会发现监控系统设计都大同小异,在这里不过多强调。
2.2 业务方
主要看接入,按照接入的项目类型,可以分为
- h5 项目
- RN项目(其他native项目的思路是一样的)
2.3 接入形式
- h5 项目接入日志上送,用 script 引入 js-sdk(第3方js 或 cdn js)。不使用 npm 包,一是为了避免项目构建,有多余模块参与。二是该js-sdk的更新,不需要业务方发布,只需要平台方发布。
- RN项目接入,用 npm 方式引入。
2.4 日志api二次封装
为什么二次封装?
理由有3:
- 1、平台方或者第3方提供的日志js-sdk提供的api,对我们来说是黑盒子,我们不能因为使用该日志js-sdk提供的api报错,导致业务项目功能异常。
- 2、上送日志内容,我们想更加规范和语义化,让人一眼通过日志看出问题。
- 3、我的经验,80%以上情况下是日志上送的内容,是接口请求的内容。我们不可能单独对每个接口请求,手动接入日志上传的人力太大了,需要在接口请求的公共方法加入日志内容上传。
2.4.1 日志js-sdk 的 try catch 处理
function dealLoggerFn (fnKey, ...arg) {
try {
window.logger[fnKey](...arg)
} catch (e) {}
}
const logger = {
info: (...arg) => dealLoggerFn('info', ...arg),
warn: (...arg) => dealLoggerFn('warn', ...arg),
error: (...arg) => dealLoggerFn('error', ...arg)
}
export default logger
2.4.2 日志内容规范
举个例子,nginx日志,如截图,我们能通过接口日志,看出是什么业务场景出错了吗?显然不能。
所以,我们希望看到下面这样日志
`商场模块-购物页-生成预付单号接口code!=000000`,请求地址,请求入参,请求出参,页面url
我们看到第1句号,就知道哪项目的哪个页面的哪个功能下哪个接口报错了,我们都不需要查看接口请求日志具体内容,就能快速定位问题,大大提高我们排查问题效率。
那怎么定制日志内容规范,可以参看
制定业务方-通用日志内容规范
logger.error(`${模块名称}-${页面名称}-${场景名称}`,`${补充信息}`,`${页面路径}`)
这个使用所有业务场景模版,然后在根据这个模版内容,定制更加细致的模版内容。
ps: 你会发现页面路径日志,为什么放在最后?理由2点,1、我们大多数情况看到前面,就只到哪个接口报错了,页面路径往往不需要看,2、我日志内容上传有字符长度限制,页面路径往往是不太重要,所以放到最后。
网络异常兜底场景日志模版
格式:
logger.error(`${模块名称}-${页面名称}-${具体什么网络异常}`, `${页面的路径}`)
接口异常场景日志模版
接口入参处理异常,格式:
logger.error(`${模块名称}-${页面名称}-${接口名称}`, `${接口入参处理异常}`, `${接口路径}`, `${接口入参}`, `${异常原因或内容}`, `${页面的路径}`)
接口出参httpCode异常,格式:
logger.error(`${模块名称}-${页面名称}-${接口名称}`, `${接口出参httpCode异常}`, `${接口路径}`, `${接口入参}`, `接口出参(包含httpCode)`, `${页面的路径}`)
接口出参code!=000000,格式:
logger.error(`${模块名称}-${页面名称}-${接口名称}`, `${接口出参code!=000000}`, `${接口路径}`, `${接口入参}`, `${接口出参(包含httpCode)}`, `${页面的路径}`)
2.4.3 接口请求日志内容自动上传
${模块名称}-${页面名称}-${接口名称} ,前2个可以自动获取,模块名称可以定义1个全局变量实现,页面名称通过document.title 来获取。当然,如果是RN项目,页面title显示区域可能是一个RN组件,那我们就在设置页面title的时候,设置一个全局变量来解决。接口名称,这个不太能自动获取,必须由开发透传。
所以,日志内容自动上传,并且语义化,其实并不能做到,业务开发完全不出人力。还需要做一点事,把接口的中文名称做为接口请求方法入参。如下:
// 生成预付单号接口
// 接口地址
export async function fetchEg1 (params) {
const res = await request({
url: '/your/request/path',
method: 'post',
data: params,
+ sceneName: '生成预付单号'
})
return res
}
当然,我们不传,也应该上传日志,具体的封装思路如下:
function request ({url, params, method, sceneName }) {
try {
const options = dealParams(params)
const res = fetch(method, url, options)
if (res && res.code !== '000000') {
logger.error((sceneName, '接口请求code!=000000', params, url, res)
}
} catch (e) {
logger.error(sceneName, '接口请求异常', params, url,error)
}
}
function dealParams (params) {
try {
// 接口入参处理
// ...
} catch (e) {
logger.error(sceneName, '接口请求入参处理
异常', params, url,error)
}
}
在对logger处理一下
function dealLoggerFn (fnKey, ...arg) {
try {
+ const [sceneName, otherArg] = arg
+ const firstParam = `${window.__MODULE_NAME__}-${document.title}-${sceneName}`
+ const lastParam = location.url
+ window.logger[fnKey](firstParam,...otherArg, lastParam)
} catch (e) {}
}
const logger = {
// ...
error: (...arg) => dealLoggerFn('error', ...arg)
}
export default logger
2.4.4 补充一下,页面显示网络异常兜底页面
页面显示网络异常兜底,不论使用组件,还是执行js方法实现的。那么组件或js方法必须有一个必选参数是日志内容,日志内容必须特殊标识。
例如下面:
function showNetWorkError (logMsg) {
logger.error(`${模块名称}-${页面名称}-${logMsg}`, 'network-error', `${页面的路径}`)
// todo
}
我曾经历过一个项目,灰度发布,页面时不时显示显示网络异常兜底。仓库代码里有31的场景显示网络兜底,开发没有做任何日志上传,该项目是ssr项目,本地无法模拟,只能上灰度,恰好那几天版本管控,不许发布灰度,所以只能手动排查,1个开发足足排查2天才排查出来。
之后,我每经历一个项目,显示网络异常兜底,我都会封装,将第1个参数设置成,必选参数,且是异常日志信息。
3、业务维度
按照业务维度,分为业务监控和技术监控。
3.1 业务监控
业务监控通常根据数据分析业务价值,作为开发要足够熟悉功能平台功能,找到能够帮助我们开发的用处。我个人经验是有3个使用经验用处:
- 帮助业务找到新的方向提高业务价值
- 帮助开发排查问题
- 帮助开发采用更合理方案
具体功能大概下面这些:
用户行为分析
漏斗分析
分布分析
看板分析
……
3.1.1 用户行为分析
用户行为分析,展示用户访问那些页面,在每个页面经历的交互的记录。
这个功能我个人体验,主要可以帮助我们定位问题。举个例子:
有个客户投诉,自己购买商品不成功,我们通过用户行为分析,发现用户进行过绑卡,但这个绑卡的页面不是我们的业务团队的,是其他团队。如果我们按照日志查询的话,我们只能查自己业务团队的日志,很难发现是其他团队问题。通过这个很快定位到其他团队问题,联系他们协助解决。
3.1.2 漏斗分析
所谓漏斗功能就是,统计某个功能的每一步操作的埋点的转化率。
如果不了解,可以看看这篇tapdb 的漏斗分析
用处示例1:
流量统计,我们有一个静态项目,一年页面的pv到达200亿次,每次访问2M流量,简单初略估计一下cdn费用300万,其中有40%左右的用户,第1次访问都去登录,登录成功后整个页面都刷新了,相当于访问2次,加载2次静态资源,如果我们把这40%的流量解决,只能加载1次,就可以节省百万cdn费用。
这其中pv200亿次好统计,这是埋点系统基本功能。40%不太好统计,但是如果你知晓,埋点系统有漏斗功能,那就好统计。
用处实例2:
有1个项目,用户购买够某个商品,需要经历7个步骤,每个步骤转化率如下
从这个流转率,我们可以看出步骤2的流转率比较低,也就是优化步骤2带来提高转化率,相对其他步骤是容易,事实也证明,我们在按钮加上一个奖励角标吸引用户,步骤2转化率提高到45%,整体转化率就提高了50%,非常可观。
3.1.2 分布分析
分布分析,可以适用看1个页面流转到下个页面的量。
实例1,下面是个A页面到下个页面的流量分布,我们发现G页面的流量比较高,单业务价值高,后来我们跟产品沟通,发现G页面可以在某些场景下线了。于是我们把G页面入口做弱化显示,其他几个页面的流量提高很多了。
3.1.3 看板分析
看板分析,有很多统计,我就说2个,设备统计、页面的来源浏览量。
3.1.3.1 设备统计
设备统计,统计的是某个页面,在各个操作系统访问量。
我们经常遇到这样的问题,遇到某个低系统兼容问题,举个例子:
我们遇到ios8的兼容问题,整个部分没有ios8的手机,就算你做了,也没法测。后来我们查了一下,ios8占有率只有万分之一不到,显然我们没必要的解决兼容问题,只需要做一个用户升级系统引导提示。假设没有这快数据支持,可能产品不认同。
3.1.3.2 页面的来源浏览量
我有一个免登陆页面,帮助我们自己团队快速实现免登。由于这个页面实现免登非常好用,不需要什么开发人力,后面产品人员调整,产品把这个带到其他团队了,实际上我们也是业务方,不是平台方。实际上免登效果,可以在各个团队页面内部实现。
后面出现一个严重问题,性能指标非常差,流量又是200万uv,严重影响到团队的kpi,性能技术优化都做到了极致,但还是很差。
我领导跟大领导反馈,性能优化不掉,这个页面做下线处理,大领导不同意,说下线的影响面根本评估不出来,没数据支撑,后面我了解这个事,通过调研,发现监控平台有统计页面的各个入口来源数据,可以评估影响面。
3.1.4 总结一下
对于业务监控,更多在于实践,虽然这部分监控应该由产品掌握,但是要记住,产品很多手收集数据是不准确且是常态,需要开发反复确认。
4、技术监控
4.1 监控记录
页面性能指标记录、请求记录、js error记录,网上有大量文章,也是大同小异。在我的经验,开发者大部分很容易掌握,且兴趣很高,调研一下很快掌握。所以这块,我就不详解,贴几份文章。
4.1.1 页面性能指标记录
对于新手来说,提到性能,就想到性能优化,js、css文件压缩、缓存,没考虑指标问题。一般有经验的,提到性能,应该想到是指标,因为是做是否做性能优化依据,不是所有的时候,都要做性能优化,有的时候业务价值高,优先实现业务。另外,性能指标,也是我们优化方案的指导,后续,我会写一篇性能优化操作手册。
补充一下: 工作久了,页面性能优化,对于很多时候,有时候是开发者一厢情愿,说自己要做性能优化,或某个kpi指标下来,包含性能优化。但实际上,是否要做性能优化的价值,大部分开发只能说页面响应更快,只有定性的认知,更快带来什么却说出所以然。
那么这就面临一个问题,开发做性能优化的人力,产品经理可能不认同,认为你做的这个性能优化是浪费人力,开发又不能说什么定量的价值来,在需求排期,性能技术优化需求做价值评估时,因价值不大排不下来,导致开发想做性能优化却做不了,我相信很多团队发生这事情。
这里话,我给出解决方案,希望能给遇到相同问题的开发,带来思路。
假设我们有1个购买商品页面,95线页面渲染指标,要怎么做性能优化需要说服产品。解决问题思路很简单,拿到在95线上的购买转化率是多少高于在95线以下的。
那怎么去拿到这个数据了? 方案一:询问公司平台方(架构部)有无这样能力,如果有,那就好办了,如果没有,提需求给平台研发。 方案二:方案一大概率是没有,且平台方大概率不可能开发,怎么办?自己搞,当然,业务开发肯定没太多人力,需结合平台现有的功能去弄。当时我想一招,按照公司95线计算公式,拿到页面的性能指标值,对比公司95线合格线的值,如果大于埋1个点,如果小于在埋1个点,结合漏斗工具不就能获取想要的数据。具体可以看下图
不了解95线,看看这个# 大厂里一直讲的p99,p95到底是什么?
4.1.2 请求记录
上面的【日志api二次封装】方法已经提到了,这个就不提了。
4.1.3 js error记录
这个业务开发来说不难,难得是根据 js error 记录,找到业务价值高的,优先解决。js error 本身时时发生,不是所有js都需要解决的。下面是我自己定 js error 修复的优选级表格。
| js error 错误 | 影响面 | 解决方案 | 解决后提升价值 |
|---|---|---|---|
| xxx 错误 | 购买页面验密js报错,影响到1%的用户 | xxx | 购买率提升 |
| xxx 错误 | 第3方js内部报错,业务功能无影响 | xxx | / |
其他一些文章的参考点
4.2 监控告警
监控记录帮助我们,记录错误,如果错误我们没有查看,那么这个错误我们也不知道,所以需要告警,通过邮件短信等消息通知我们,即监控告警。
当然监控告警是有配置规则的,主要的是1分钟报错了多少这样次数错误,或者什么访问次数突然下跌幅度非常大。
给一个参考文章阿里云监控告警
总结一下
1、监控统计,还有很多没有提,本文主要说的面,真正的技术面技术面不多,很多是业务面的,在我的理解,业务面并不比技术面不重要。
2、以上很多知识点,很多点是单独列出,实际上需要系统的了解。
3、对于业务开发来说监控是3部曲,接入-分析-告警 - 接入(方法封装,内容规范,规范里包含监控分类) - 分析(分析,找到有价值东西) - 严重告警,及时通知相关人
(完)