這套前端監控系統用到的技術棧是:React+MongoDB+Node.js+Koa2。將性能和錯誤量化,解決業務和開發都不知道,只有用戶知道的問題,提升業務穩定性。
  因為自己平時喜歡吃菠蘿,所以就取名叫[菠蘿系統](https://github.com/pwstrick/pineapple)。其實在很早以前就有這個想法,當時已經實現了[前端的參數搜集](https://github.com/pwstrick/Primus),只是后臺遲遲沒有動手,也就拖著。
* 目前完成的還只是個雛形,僅僅是搜集了錯誤和相關的性能參數。
* 后臺樣式采用了封裝過的matrix。
* 分析功能還很薄弱,只是做了簡單的演示,并且各種基礎功能還有待完善。
* 后面打算強化數據分析,并且還要實現錯誤的回放機制,思路的話以前也調研過,參考之前的[一篇文章](https://www.cnblogs.com/strick/p/12206766.html)。
  現在的這個系統還只能算是個玩具,后期還需要雕琢雕琢。下面是這套系統的目錄結構。
~~~
├── pingapple --------------------------------- 菠蘿監控系統
│ ├── client -------------------------------- 系統的前端部分
│ ├── sdk ----------------------------------- 信息搜集代碼庫
│ ├── server -------------------------------- 系統的后端部分
~~~
## 一、SDK
**1)primus.js**
  在之前的《[前端頁面性能參數搜集](https://www.cnblogs.com/strick/p/5750022.html)》一文中,詳細記載了各類性能指標的計算規則,并整理到了[primus.js](https://github.com/pwstrick/Primus/blob/master/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](https://developer.mozilla.org/zh-CN/docs/Web/Events/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的最后面。
~~~html
<head>
<script>
window.pineapple || (pineapple = {});
pineapple.param = {
"token": "dsadasd2323dsad23dsada"
};
</script>
<script src="js/pineapple.js"></script>
</head>
~~~
## 二、服務端
**1)Koa**
  [Koa](https://koa.bootcss.com/)是由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是[下載界面](https://www.mongodb.com/download-center/community)),既沒有表、行等概念,也沒有固定的模式和結構,所有的數據以文檔(一個對象)的形式存儲。但其使用方式和關系型數據庫相似,并且還支持對數據建立索引,適用于高并發讀寫、海量數據存儲和實時分析等。
:-: 
圖1
  注意,在安裝時默認會下載[MongoDB Compress](https://www.mongodb.com/download-center/compass)(一個可視化的MongoDB工具),默認下載會非常慢,建議自行下載,該工具的界面還是蠻清爽的,如圖2所示。
:-: 
圖2
  在Mac上配置MongoDB比較麻煩,不像Windows那樣一件安裝,需要一些步驟,廢了點力氣才裝好,下面是執行的命令。
~~~
sudo mongod --dbpath=/Users/pw/data
~~~
**3)Mongoose**
  [Mongoose](https://mongoosejs.com/)是MongoDB的一個ORM(Object-Document Mapper,對象文檔映射)工具,可在Node.js環境中執行,封裝了MongoDB操作文檔的[常用方法](https://mongoosedoc.top/docs/index.html),包括引入數據庫連接(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](http://faisalman.github.io/ua-parser-js/),四年前就關注過,當時GitHub上只有1K多個關注量,現在已經翻了4倍。
~~~
npm install --save ua-parser-js
~~~
**6)假數據**
  制作一套合適的假數據,新增命令“npm run data”,初始化數據,便于展示。
## 三、后臺
**1)UI**
  后臺模板采用了之前封裝過的[Matrix](https://github.com/pwstrick/grape-skin),但不會依賴Bootstrap框架。
  將整個頁面分成五塊,分別是導航、側邊欄、面包屑、底部欄以及主體。
  安裝react-router的history,用于路由。
~~~
npm install --save history
~~~
  期間也會安裝各類依賴包,例如不支持在類中直接聲明屬性等。
  在使用的過程中,ESLint會不時的彈出各種錯誤和警告,期間就不停的修改問題或查找相關配置忽略部分限制。
  后臺的側邊欄和面包屑等部分,會隨著URL的不同而發生狀態變化,本來想用多頁實現,但配置要改很多,就依然做成一個SPA,只是稍微做了些改動。
  組件庫采用了流行的[Ant Design](https://ant.design/components/button-cn/),調用了按鈕、單選框、日期等組件。
~~~
npm install --save antd
~~~
  圖表庫使用的是[ECharts](https://www.echartsjs.com/zh/index.html),目前只用到了折線圖和餅圖。在引用圖表時,為了優化構建,采取了按需引用的手段。
~~~
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
*****
> 原文出處:
[博客園-Node.js躬行記](https://www.cnblogs.com/strick/category/1688575.html)
[知乎專欄-Node.js躬行記](https://zhuanlan.zhihu.com/pwnode)
已建立一個微信前端交流群,如要進群,請先加微信號freedom20180706或掃描下面的二維碼,請求中需注明“看云加群”,在通過請求后就會把你拉進來。還搜集整理了一套[面試資料](https://github.com/pwstrick/daily),歡迎閱讀。

推薦一款前端監控腳本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不僅能監控前端的錯誤、通信、打印等行為,還能計算各類性能參數,包括 FMP、LCP、FP 等。
- ES6
- 1、let和const
- 2、擴展運算符和剩余參數
- 3、解構
- 4、模板字面量
- 5、對象字面量的擴展
- 6、Symbol
- 7、代碼模塊化
- 8、數字
- 9、字符串
- 10、正則表達式
- 11、對象
- 12、數組
- 13、類型化數組
- 14、函數
- 15、箭頭函數和尾調用優化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、類
- 21、類的繼承
- 22、Promise
- 23、Promise的靜態方法和應用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基礎實踐
- 3、WebRTC視頻通話
- 4、Web音視頻基礎
- CSS進階
- 1、CSS基礎拾遺
- 2、偽類和偽元素
- 3、CSS屬性拾遺
- 4、浮動形狀
- 5、漸變
- 6、濾鏡
- 7、合成
- 8、裁剪和遮罩
- 9、網格布局
- 10、CSS方法論
- 11、管理后臺響應式改造
- React
- 1、函數式編程
- 2、JSX
- 3、組件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表單
- 8、樣式
- 9、組件通信
- 10、高階組件
- 11、Redux基礎
- 12、Redux中間件
- 13、React Router
- 14、測試框架
- 15、React Hooks
- 16、React源碼分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基礎
- 4、webpack進階
- 5、Git
- 6、Fiddler
- 7、自制腳手架
- 8、VSCode插件研發
- 9、WebView中的頁面調試方法
- Vue.js
- 1、數據綁定
- 2、指令
- 3、樣式和表單
- 4、組件
- 5、組件通信
- 6、內容分發
- 7、渲染函數和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、數據類型
- 2、接口
- 3、類
- 4、泛型
- 5、類型兼容性
- 6、高級類型
- 7、命名空間
- 8、裝飾器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系統和網絡
- 3、命令行工具
- 4、自建前端監控系統
- 5、定時任務的調試
- 6、自制短鏈系統
- 7、定時任務的進化史
- 8、通用接口
- 9、微前端實踐
- 10、接口日志查詢
- 11、E2E測試
- 12、BFF
- 13、MySQL歸檔
- 14、壓力測試
- 15、活動規則引擎
- 16、活動配置化
- 17、UmiJS版本升級
- 18、半吊子的可視化搭建系統
- 19、KOA源碼分析(上)
- 20、KOA源碼分析(下)
- 21、花10分鐘入門Node.js
- 22、Node環境升級日志
- 23、Worker threads
- 24、低代碼
- 25、Web自動化測試
- 26、接口攔截和頁面回放實驗
- 27、接口管理
- 28、Cypress自動化測試實踐
- 29、基于Electron的開播助手
- Node.js精進
- 1、模塊化
- 2、異步編程
- 3、流
- 4、事件觸發器
- 5、HTTP
- 6、文件
- 7、日志
- 8、錯誤處理
- 9、性能監控(上)
- 10、性能監控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 監控系統
- 1、SDK
- 2、存儲和分析
- 3、性能監控
- 4、內存泄漏
- 5、小程序
- 6、較長的白屏時間
- 7、頁面奔潰
- 8、shin-monitor源碼分析
- 前端性能精進
- 1、優化方法論之測量
- 2、優化方法論之分析
- 3、瀏覽器之圖像
- 4、瀏覽器之呈現
- 5、瀏覽器之JavaScript
- 6、網絡
- 7、構建
- 前端體驗優化
- 1、概述
- 2、基建
- 3、后端
- 4、數據
- 5、后臺
- Web優化
- 1、CSS優化
- 2、JavaScript優化
- 3、圖像和網絡
- 4、用戶體驗和工具
- 5、網站優化
- 6、優化閉環實踐
- 數據結構與算法
- 1、鏈表
- 2、棧、隊列、散列表和位運算
- 3、二叉樹
- 4、二分查找
- 5、回溯算法
- 6、貪心算法
- 7、分治算法
- 8、動態規劃
- 程序員之路
- 大學
- 2011年
- 2012年
- 2013年
- 2014年
- 項目反思
- 前端基礎學習分享
- 2015年
- 再一次項目反思
- 然并卵
- PC網站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端學習之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 2024年
- 日志
- 2020