这套前端监控系统用到的技术栈是: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. JavaScript Basic

    Exercise-1 Write a JavaScript program to display the current day and time in the following format. T ...

  2. MyBatis通过注解方式批量添加、修改、删除

    唯能极于情,故能极于剑 注: 本文转载于:CodeCow · 程序牛 的个人博客:http://www.codecow.cn/ 一.数据库实体DO public class User implemen ...

  3. Kivy中显示汉字的问题

    1. kivy中显示中文乱码和提示错误的原因: 编码问题 字体问题 2. 字体问题的解决 可以下载支持中文的字体文件ttf,我这里使用了微软雅黑中文简体msyh.ttf.我们在编写布局时可以直接在相关 ...

  4. PowerDesigner使用教程(一)

    一.PowerDesigner简介 PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据 ...

  5. 5.Linux的启动过程和系统指令

    1.Linux的启动过程 作为一台计算机,启动它的第一步是加电自检,也就是给电脑用电然后按电源按钮开机.加电之后的运行步骤:(1)加载bios,然后检查硬盘信息 (2)读取MBR的配置(MBR就是硬盘 ...

  6. Python学习之路【第一篇】:Python简介与入门

    Python简介 一.什么是Python Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言 ...

  7. 一个基类Person的多个派生类 代码参考

    #include <iostream> #include <cstring> using namespace std; class Person { protected: ch ...

  8. idea创建maven项目慢的原因以及解决方案

    问题分析;在idea中maven项目所依赖的jar包,默认是从中央仓库直接下载jar包,不管jar包是否在本地仓库存在,所以导致idea创建maven项目速度慢,那么要解决这个问题,那么将idea设置 ...

  9. Ubuntu18.04兼容Python2.7、Python3.6、Python3.8以及pip、pip2、pip3问题

    Ubuntu18.04兼容Python2.7.Python3.6.Python3.8以及pip.pip2.pip3问题 此为记录我重装Ubuntu后安装Python的过程 安装Python3.8 目前 ...

  10. Rocket - tilelink - toBools

    https://mp.weixin.qq.com/s/UGMH8EoaVcFkkQW-l4HLWg   分析toBools在Intellij中显示为红色的问题.   ​​   1. 问题   在TLA ...