这套前端监控系统用到的技术栈是:React+MongoDB+Node.js+Koa2。将性能和错误量化。因为自己平时喜欢吃菠萝,所以就取名叫菠萝系统。其实在很早以前就有这个想法,当时已经实现了前端的参数搜集,只是后台迟迟没有动手,也就拖着。

  • 目前完成的还只是个雏形,仅仅是搜集了错误和相关的性能参数。

  • 后台样式采用了封装过的matrix。

  • 分析功能还很薄弱,只是做了简单的演示,并且各种基础功能还有待完善。

  • 后面打算强化数据分析,并且还要实现错误的回放机制,思路的话以前也调研过,参考之前的一篇文章

  现在的这个系统还只能算是个玩具,后期还需要雕琢雕琢。下面是这套系统的目录结构。

├── pingapple --------------------------------- 菠萝监控系统
│ ├── client -------------------------------- 系统的前端部分
│ ├── sdk ----------------------------------- 信息搜集代码库
│ ├── server -------------------------------- 系统的后端部分

一、SDK

1)primus.js

  在之前的《前端页面性能参数搜集》一文中,详细记载了各类性能指标的计算规则,并整理到了primus.js中。

  本次将在primus.js的基础上做适当的修改,包括删除代理、测速、资源信息等功能,改变部分性能指标的计算规则,例如从浏览器发起HTTP请求算起,忽略浏览器重定向的时间等。

2)错误处理

  完善错误处理,将错误分成三类:runtime、load和Promise。在window的error事件中,处理前两种错误。像img元素载入的图片地址不存在,就会执行formatLoadError()函数;像变量未定义,就会执行formatRuntimerError()函数。

window.addEventListener("error", function (event) {
var errorTarget = event.target;
// 过滤 target 为 window 的异常
if (
errorTarget !== window &&
errorTarget.nodeName &&
LOAD_ERROR_TYPE[errorTarget.nodeName.toUpperCase()]
) {
handleError(formatLoadError(errorTarget));
} else {
handleError(
formatRuntimerError(
event.message,
event.filename,
event.lineno,
event.colno,
event.error
)
);
}
}, true
);

  将window绑定unhandledrejection事件后,就会在Promise被拒绝且没有reject的回调函数时触发。

window.addEventListener(
"unhandledrejection",
function (event) {
// console.log('Unhandled Rejection at:', event.promise, 'reason:', event.reason);
handleError({
type: ERROR_PROMISE,
desc: event.reason,
stack: "no stack"
});
},
true
);

3)初始化

  由于要计算白屏时间,DOM时间等,所以位置不能随便放,得要放在head的最后面。

<head>
<script>
window.pineapple || (pineapple = {});
pineapple.param = {
"token": "dsadasd2323dsad23dsada"
};
</script>
<script src="js/pineapple.js"></script>
</head>

二、服务端

1)Koa

  Koa是由Express原班人马打造的Web轻量框架,通过组合各种中间件来避免繁琐的回调函数嵌套,当前使用的版本是V2。

npm install --save koa

  使用的Koa脚手架:koa-generator,创建项目的结构,并且在此基础上做了调整(目录如下所示)。暂时还不会用到静态资源和视图层。

npm install -g koa-generator
├── server --------------------------------- 服务端
│ ├── bin -------------------------------- 命令
│ ├── config ----------------------------- 配置目录
│ ├── controllers ------------------------ MVC中的逻辑层
│ ├── db --------------------------------- MVC中的数据层
│ ├── public ----------------------------- 静态资源
│ ├── routes ----------------------------- 路由
│ ├── utils ------------------------------ 工具库
│ ├── views ------------------------------ MVC中的视图层
│ ├── app.js ----------------------------- 入口文件

  为了区分开发环境和生产环境,通过cross-env统一不同系统设置环境变量的方式。

npm install --save cross-env

  package.json中的命令如下,添加了环境配置。

"scripts": {
"start": "node bin/www",
"dev": "cross-env NODE_ENV=development ./node_modules/.bin/nodemon bin/www",
"prd": "cross-env NODE_ENV=production pm2 start bin/www"
}

  prd按字面意思应该是生产环境的命令,其中使用了pm2,默认没有安装。还没部署过Node.js,还不清楚里面有多少坑。

npm install --save pm2

2)MongoDB

  MongoDB是一个开源的非关系型数据库(图1是下载界面),既没有表、行等概念,也没有固定的模式和结构,所有的数据以文档(一个对象)的形式存储。但其使用方式和关系型数据库相似,并且还支持对数据建立索引,适用于高并发读写、海量数据存储和实时分析等。

图1

  注意,在安装时默认会下载MongoDB Compress(一个可视化的MongoDB工具),默认下载会非常慢,建议自行下载,该工具的界面还是蛮清爽的,如图2所示。

图2

  在Mac上配置MongoDB比较麻烦,不像Windows那样一件安装,需要一些步骤,废了点力气才装好,下面是执行的命令。

sudo mongod --dbpath=/Users/pw/data

3)Mongoose

  Mongoose是MongoDB的一个ORM(Object-Document Mapper,对象文档映射)工具,可在Node.js环境中执行,封装了MongoDB操作文档的常用方法,包括引入数据库连接(connect),定义模型(model),声明文档结构(scheme),实例化模型等操作数据库的方法。

npm install --save mongoose

  借鉴了以前PHP数据分层的思想,单独分离出数据库的连接,并抽象通用的Model层(如下所示)。

const mongoose = require("./db");
class Mongodb {
constructor(name, schema) {
//声明结构
const mySchema = new mongoose.Schema(schema, { typeKey: "$type" });
this.model = mongoose.model(name, mySchema);
}
//保存
save(obj) {
obj.created = Date.now(); //日期
const doc = new this.model(obj);
return new Promise((resolve, reject) => {
doc.save((err, row) => {
if (err) {
reject(err);
return;
}
resolve(row);
});
});
}
}
module.exports = {
model: Mongodb,
mongoose
};

4)路由

  由于发送的地址是一张gif图片,因此在处理路由时,返回本地的一张gif图,如下所示,图像地址得是绝对路径,否则无法读取。

router.get('/pa.gif', async (ctx, next) => {
const ctr = new indexController();
ctr.collect(ctx);
const url = path.resolve(__dirname, "../public/images/blank.gif");
ctx.body = fs.readFileSync(url); //空白gif图
});

5)代理分析

  在接收参数的时候分析代理所带的信息,例如浏览器、操作系统、设备等。使用的是一个第三方库:UAParser.js,四年前就关注过,当时GitHub上只有1K多个关注量,现在已经翻了4倍。

npm install --save ua-parser-js

6)假数据

  制作一套合适的假数据,新增命令“npm run data”,初始化数据,便于展示。

三、后台

1)UI

  后台模板采用了之前封装过的Matrix,但不会依赖Bootstrap框架。

  将整个页面分成五块,分别是导航、侧边栏、面包屑、底部栏以及主体。

  安装react-router的history,用于路由。

npm install --save history

  期间也会安装各类依赖包,例如不支持在类中直接声明属性等。

  在使用的过程中,ESLint会不时的弹出各种错误和警告,期间就不停的修改问题或查找相关配置忽略部分限制。

  后台的侧边栏和面包屑等部分,会随着URL的不同而发生状态变化,本来想用多页实现,但配置要改很多,就依然做成一个SPA,只是稍微做了些改动。

  组件库采用了流行的Ant Design,调用了按钮、单选框、日期等组件。

npm install --save antd

  图表库使用的是ECharts,目前只用到了折线图和饼图。在引用图表时,为了优化构建,采取了按需引用的手段。

npm install --save echarts

2)项目管理

  首先建立一个项目,然后才能分析该项目的性能和错误,如图3所示。

图3

  用弹框的形式来创建项目,使用了Ant Design的Model、Form等组件,如图4所示。

图4

3)性能分析

  在第一个折线图标签中的过滤条件包括项目、字段、日期等,性能指标按平均值呈现,可看到每个性能指标的趋势,如图5所示。

图5

  按分时日统计性能平均数,在MongoDB中计算。原先创建日期是以时间戳的形式存储的,为了便于使用Aggregate,改成字符串形式。碰到一个坑,MongoDB中的Date类型采用的是格林尼治时间,而不是当前时区的时间,也就是说存在数据库中的时间会比当前时间早8小时。

  在第二个列表标签中,可以详细看到每条记录的信息,包括代理、网络等,便于在了解趋势的前提下,获悉更为细节的内容,如图6所示。

图6

  点击ajax那一列,可弹出具体的异步请求信息,如图7所示。

图7

4)错误分析

  有三个标签,第一个也是折线图,描绘的是某个时间的错误个数;第二个是错误列表,会给出具体的错误信息,如图8所示。

图8

  第三个是饼图,饼图主要体现的是发生错误的浏览器分布情况(如图9所示),点击某一块可查看浏览器的具体版本(如图10所示)。

图9

图10

【参考资料】
PerformanceTiming

unhandledrejection 处理没有显式捕获的 Promise 异常

狼书(卷2)

Node-区分环境

Koa从零搭建到Api实现—项目部署

koa如何连接MongoDB

Koa2进阶学习笔记

如何计算首屏加载时间

Mongoose Schema Error: “Cast to string failed for value” when pushing object to empty array

Support for the experimental syntax 'classProperties' isn't currently enabled

Template string failing with Cannot read property 'range' of null

Disallow JSX props spreading (react/jsx-props-no-spreading)

TypeError: Cannot read property 'range' of null from template-curly-spacing

echarts项目的优化

使用 happypack 提升 Webpack 项目构建速度

mac下的mongoDB的安装和启动

安装MongoDB报错 mkdir: /data/db: Read-only file system

$sum mongoose

Node.js躬行记(4)——自建前端监控系统的更多相关文章

  1. Node.js躬行记(6)——自制短链系统

    短链顾名思义是一种很短的地址,应用广泛,例如页面中有一张二维码图片,包含的是一个原始地址(如下所示),如果二维码中的链接需要修改,那么就得发代码替换掉. 原始地址:https://github.com ...

  2. Node.js躬行记(1)——Buffer、流和EventEmitter

    一.Buffer Buffer是一种Node的内置类型,不需要通过require()函数额外引入.它能读取和写入二进制数据,常用于解析网络数据流.文件等. 1)创建 通过new关键字初始化Buffer ...

  3. Node.js躬行记(2)——文件系统和网络

    一.文件系统 fs模块可与文件系统进行交互,封装了常规的POSIX函数.POSIX(Portable Operating System Interface,可移植操作系统接口)是UNIX系统的一个设计 ...

  4. Node.js躬行记(15)——活动规则引擎

    在日常的业务开发中,会包含许多的业务规则,一般就是用if-else硬编码的方式实现,这样就会增加逻辑的维护成本,若无注释,可能都无法理解规则意图. 因为一旦规则有所改变,那么就需要修改代码再发布代码, ...

  5. Node.js躬行记(17)——UmiJS版本升级

    在2020年我刚到公司的时候,公司使用的版本还是1.0,之后为了引入微前端,迫不得已被动升级. 一.从 1.0 到 2.0 在官方文档中,有专门一页讲如何升级的,这个用户体验非常好. 一个清单列的非常 ...

  6. Node.js躬行记(19)——KOA源码分析(上)

    本次分析的KOA版本是2.13.1,它非常轻量,诸如路由.模板等功能默认都不提供,需要自己引入相关的中间件. 源码的目录结构比较简单,主要分为3部分,__tests__,lib和docs,从名称中就可 ...

  7. Node.js躬行记(21)——花10分钟入门Node.js

    Node.js 不是一门语言,而是一个基于 V8 引擎的运行时环境,下图是一张架构图. 由图可知,Node.js 底层除了 JavaScript 代码之外,还有大量的 C/C++ 代码. 常说 Nod ...

  8. Node.js躬行记(22)——Node环境升级日志

    公司之前所有的 Node 项目,其环境都是 8.9.4 版本,发布于 2018 年的一个比较古老的版本. 老版本有两个比较明显的问题: Node 高版本的特性和方法都无法使用. 有些第三方新版本的包无 ...

  9. Node.js躬行记(23)——Worker threads

    Node.js 官方提供了 Cluster 和 Child process 创建子进程,通过 Worker threads 模块创建子线程.但前者无法共享内存,通信必须使用 JSON 格式,有一定的局 ...

随机推荐

  1. scrapy.cmdline.execute

    scrapy的cmdline命令 1.启动爬虫的命令为:scrapy crawl (爬虫名) 2.还可以通过以下方式来启动爬虫 方法一:创建一个.py文件(这里的爬虫文件名可以自己定义,例:myspi ...

  2. 利用Jackson封装常用JsonUtil工具类

    在日常的项目开发中,接口与接口之间.前后端之间的数据传输一般都是使用JSON格式,那必然会封装一些常用的Json数据转化的工具类,本文讲解下如何利用Jackson封装高复用性的Json转换工具类. 转 ...

  3. centos 7 firewalld防火墙配置

    1.查看firewall服务状态 systemctl status firewalld 2.查看firewall的状态 firewall-cmd --state 3.开启.重启.关闭.firewall ...

  4. 【Ubuntu】Ubuntu中下载特定版本内核和设置某版本内核为默认启动内核

    0. 基本命令 uname -a # 查看当前所使用内核 dpkg -l | grep linux # dpkg后是lmn的l.查看当前操作系统的内核 dekg -l | grep linux-ima ...

  5. Java IO(十七)FIleReader 和 FileWriter

    Java IO(十七)FIleReader 和 FileWriter 一.介绍 FIleReader 和 FileWriter 是读写字符文件的便利类,分别继承于 InputStreamReader ...

  6. Javascript函数闭包详解(通俗易懂

    许多书上闭包过于复杂讲解难懂,自己理解了一下并总结啦~ 讲闭包之前,需要先明白以下几个概念. 总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域. 1.执行上下文(executi ...

  7. python调用大漠插件教程03窗口绑定实例

    怎样利用注册好的大漠对象来绑定窗口? 直接上代码,根据代码分析 from win32com.client import Dispatch import os from win32gui import ...

  8. seacms_6.4.5 前台任意代码执行漏洞分析

    环境搭建 1.下载安装包 下载地址: 链接:https://pan.baidu.com/s/1uw_VnxnvG4GGEae4TRsGGw 密码:cd48 2.常规安装 漏洞复现 poc1: http ...

  9. 深度学习玩LOL-游戏助手-概述

    目标 用深度学习技术实现常规英雄联盟游戏助手的主要功能,功能主要包括:英雄推荐,装备推荐,地图预警等. 基本思路 首先使用图像分类算法模型对游戏客户端内的英雄头像进行截取和识别. 使用线性回归模型对可 ...

  10. Java实现 LeetCode 368 最大整除子集

    368. 最大整除子集 给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (Si,Sj) 都要满足:Si % Sj = 0 或 Sj % Si = 0. 如果有多个目标子集, ...