【前端监控】监控数据都有什么

2021-09-10 11:32:43 浏览数 (1)

前端监控系列,SDK,服务、存储 ,会全部总结一遍,写文不易,点个赞吧

监控的内容我们已经说了很多了,那么我们一般上报一条监控内容都具体包含什么数据呢

今天就来详细列举一下

本文列出的数据会这样说明

1、有什么数据

2、作用是什么

3、怎么获取

我会给每个具体分个类,按分类来逐个说明

数据大概分为下面几类

1、监控点数据

2、用户信息

3、设备信息

4、项目信息

5、日志信息

下面就按这个分类来说明里面包含的详细数据

监控点数据

这个就是每个监控点类型相应的数据,像接口请求信息,静态资源,首屏测速等等

具体可以在相应的文章中查看

1、自动抓取接口请求数据

2、静态资源测速&错误上报

3、页面错误监控

4、单页首屏测速

所以这里就不一一列举了,本文主要是讲一些公共的监控数据

不过这里简单说个接口信息的监控数据

cgi

接口链接

status

状态码

body

请求体

responce

响应

reqHeader

请求header

code

接口状态码

cost_time

接口耗时

用户信息

包括用户的特征,唯一标识等等

uin

用户的账号信息。如果是QQ 登陆,就是QQ 号,微信登陆就是 微信uin(不是微信号),或者你们公司自己登录体系下的账号

下面是获取 qq 或者 微信uin

代码语言:javascript复制
function getCookie(name) {
  const cookieReg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);
  const matches = document.cookie.match(cookieReg);

  return !matches ? '' : decodeURIComponent(matches[2]);
}
function getQQUin() {
  const uin = getCookie('p_luin') || getCookie('p_uin') || getCookie('uin');
  return uin ? parseInt(uin.replace(/[^d]/g, ''), 10).toString() : null;
}

function getWeixinUin() {
  const uidUin = getCookie('uid_uin');
  return uidUin || null;
}

微信uin 是创建微信时分配的独有的uin,不是微信号,因为微信号能改,并不唯一。大概像这样 14411xxxxxxxx134

地区

国家、省、市 这些位置信息,在服务端通过客户端ip 做解析

可以使用 npm 包 node-ip2region 来解析

简单使用如下

代码语言:javascript复制
const searcher = require('node-ip2region').create();
const res = searcher.btreeSearchSync('120.68.22.68');

console.log(res);

返回结果如下

代码语言:javascript复制
{
  city: 0,
  region: '中国|0|新疆|伊犁|电信',
}

具体可以看

https://github.com/lionsoul2014/ip2region

设备标识 - aid

页面初始化的时候,会给用户分配一个尽可能唯一的id标识,存在localstorage 中。

可以使用 uuid 生成,或者自己写一个

代码语言:javascript复制
const getRandomId = () => {
  const aid = 'xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0;
    const v = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
  return aid;
}

会话标识 - sessionId

同样也是唯一的id 标识,但是表示的是会话id,存在 sessionStorage 中。

比如你这次打开页面,为你生成一个,接着你的任何操作都会带上这个id。

下次再打开页面时,会重新生成。

生成方式和 aid 一样

设备信息

关于设备信息的数据就比较多了,对于前端比较重要,前端看重兼容性,各端的支持五花八门,定位问题需要考虑这一点

设备信息,一般我们可以通过 navigator.userAgent 来获取,拿到以下这些字段

os

系统以及版本

brand

品牌(苹果,华为,小米 等)

device

产品型号(Huawei P30、Mate40...等等)

engine

浏览器渲染引擎

browser

浏览器以及版本

具体我们会使用一个 npm 包来解析拿到相应的数据

可以看一下

https://github.com/faisalman/ua-parser-js

使用方式如下

代码语言:javascript复制
const parser = require('ua-parser-js');

const sliceVersion = (version, count = 2) => {
  if (!version) return '';
  return version.split('.').slice(0, count).join('.');
};

const parserUa = (ua) => {
  const { browser = {}, os = {}, engine = {}, device = {} } = parser(ua);

  return {
    browser: browser.name
      ? `${browser.name}(${sliceVersion(browser.version)})`
      : '',
    device: device.vendor ? `${device.vendor} - ${device.model || ''}` : '',
    os: os.name ? `${os.name} - ${os.version || ''}` : '',
    engine: engine.name
      ? `${engine.name}(${sliceVersion(engine.version)})`
      : '',
    brand: device.vendor || '',
  };
};

比如 userAgent 是

Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1

可以解析得到

关于渲染引擎,大概有这么几种

1、IE浏览器 (Trident内核) 2、Firefox (Gecko内核) 3、Safari (Webkit内核) 4、Chrome (Blink内核) 5、Opera (原为Presto内核,现为Blink内核) 6、QQ/WX (原为Webkit内核,现为Blink内核)

网络状态 netType

用户网络状态很重要,有可能用户加载慢时因为网络不行,所以需要记录这个指标

具体先从 navigator.userAgent 中获取,因为微信会将网络类型注入 ua。

看一个 wx 的 userAgent 例子

Mozilla/5.0 (Linux; Android 10; VOG-AL00 Build/HUAWEIVOG-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.72 MQQBrowser/6.2 TBS/045811 Mobile Safari/537.36 MMWEBID/2264 MicroMessenger/8.0.11.1980(0x28000B3B) Process/tools WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64

其次我们再从 navigator.connection 中获取,但是兼容性有点问题,iOS 不支持这个。

代码如下

代码语言:javascript复制
const NetworkTypeNum = {
  unknown: 'unknown',
  wifi: 'wifi',
  net2g: '2g',
  net3g: '3g',
  net4g: '4g',
  net5g: '5g',
  net6g: '6g',
};

const parseNumberType = (net) => {
  net = String(net).toLowerCase();
  if (net.indexOf('4g') >= 0) return NetworkTypeNum.net4g;
  if (net.indexOf('wifi') >= 0) return NetworkTypeNum.wifi;
  if (net.indexOf('5g') >= 0) return NetworkTypeNum.net5g;
  if (net.indexOf('6g') >= 0) return NetworkTypeNum.net6g;
  if (net.indexOf('3g') >= 0) return NetworkTypeNum.net3g;
  if (net.indexOf('2g') >= 0) return NetworkTypeNum.net2g;
  return NetworkTypeNum.unknown;
};

const getNetworkType = function () {
  let netType = '';

  // 优先从 ua 中获取(微信会将网络类型注入 ua)
  const arr = navigator.userAgent.match(/NetType/(w )/);
  if (arr) {
    [, netType] = arr;
  } else if (navigator.connection) {
    // navigator.connection 存在兼容性问题,当前不支持 ios
    netType = navigator.connection.effectiveType || navigator.connection.type;
  }

  if (!netType) {
    netType = 'unknown';
  }
  const net = parseNumberType(netType);
  return;
}

客户端 ip

客户端ip 需要在服务端获取了

代码语言:javascript复制
function getClientIp(req) {
  try {
    const xff = (
      req.headers['X-Forwarded-For']
      || req.headers['x-forwarded-for']
      || ''
    ).split(',')[0].trim();

    return xff
      || req.connection.remoteAddress
      || req.socket.remoteAddress
      || req.connection.socket.remoteAddress;
  } catch (ex) {

  }

  return '0.0.0.0';
}

网络运营商 ISP

就是 中国移动,联通,电信 那些数据,在服务端通过 ip 解析拿到,和上面解析省市区一样

可以使用 npm 包 node-ip2region 来解析

简单使用如下

代码语言:javascript复制
const searcher = require('node-ip2region').create();
const res = searcher.btreeSearchSync('120.68.22.68');

console.log(res);

返回结果如下,最后一个就是运营商

代码语言:javascript复制
{
  city: 0,
  region: '中国|0|新疆|伊犁|电信',
}

具体可以看

https://github.com/lionsoul2014/ip2region

这一类数据可以帮助你查看用户画像,比如建立像下面这些可视化图

项目信息

主要是页面相关的信息

页面 url

就是页面url 。可以便于根据 url 定位出所有数据,包括错误、资源、请求、性能 等数据,全方位评测出一个页面的质量。

还可以页面作为维度,比较数据

环境 env

一般环境分为 local 本地开发环境、test 线上测试环境、pre 预发布环境、prod 正式环境。

告警都是设置正式环境,测试环境错误日志可不要浪费时间排查

项目 project

团队有很多项目,上报的数据肯定要带上项目名。便于你排查过滤日志

监控npm包版本 sdk_version

项目引入的 监控 sdk 的版本也要记录。

如果因为sdk 导致日志记录的数据有问题,sdk 修复更新了版本之后,还存在有问题的日志。需要查看它依赖的是否是更新之后的版本

项目更新标识 build_time | project_version

这个很重要,作用和上面差不多

比如你线上出现了一个很严重的bug,已经触发告警了。

你修复之后,需要看线上运作情况

因为仍然会存在错误日志,所以需要一个字段去筛选修复之后的线上日志。

可以使用项目打包构建的世界,可以使用项目版本号。不过考虑到一般的业务项目,不太会更新版本号

所以最好是在构建配置中注入一个构建时间变量,供SDK 获取上报

日志信息

日志等级 level

在 离线日志 中说过,日志一般分有等级,来区分重要性,是否需要请求上报,存到本地作为离线日志

代码语言:javascript复制
const LOG_LEVEL = {
  trace: 10,
  debug: 20,
  info: 30,
  warn: 40,
  error: 50,
  fatal: 60,
};

日志类型 log_type

上报的日志有很多类型,就像我们之前说的各种监控点一样

1、离线日志

2、页面错误(细分很多种)

3、接口信息

4、静态资源(细分很多种)

5、首屏时间

等等

代码语言:javascript复制
const LOG_TYPE = {
  pv: 'pv',
  promise_error: 'promise_error',
  offline: 'offline',
  cgi_speed: 'cgi_speed',
  resource_speed: 'resource_speed',
  ....
}

日志时间 log_time

日志发生的时间,一般是时间戳 Date.now()

日志信息 message

一般用于项目内自定义上报存放文字信息的,便于查找对应日志

比如上报 message="报名按钮点击",你就会搜索这个条件,看活动上线一共有多少人报名点击

日志数据 addition

一般用于项目内自定义上报存放 调试数据,便于排查哪个环节出了问题,类似于debug一样,是否在处理数据过程中出现了问题

比如说项目中 catch 拿到的error,或者 表单提交时的数据。

你可能会说,提交的数据,我直接看接口请求的body 不就好了吗,但是其实有时你的函数处理出问题,甚至都没走到请求的这一步。

数据出问题的概率是很大的,不是像你本地开发调试一样规规矩矩的数据,每一步的数据处理都要记录下来,特别是那种format 的处理函数,入口和出口的数据都必须要记录上报

最后

看完上面这些字段,可以基本清楚,字段的设置无非是为了方便你筛选合适日志帮助排查,尽可能帮助还原问题场景,实打实从数据定位问题,不要靠猜想,靠自己偶然复现

鉴于本人能力有限,难免会有疏漏错误的地方,请大家多多包涵, 如果有任何描述不当的地方,欢迎后台联系本人,领取红包

0 人点赞