Easy-Monitor
Easy-Monitor是一个轻量级的Node项目性能监控工具,能在线上生产环境运行,主要帮助开发者找出执行时间最久或者超出预期的一系列函数,以及运行过程中v8引擎无法优化的一系列函数。
这个项目源于之前做的解析v8-profiler日志命令行工具,有兴趣的可以看下之前的文章:
按照之前所说的方式,对于开发者来说依旧非常的麻烦,并且不能进行线上运行时的调试,所以就整合集成了下诞生了Easy-Monitor。
I. 特点
- 轻量级
- 运行时
- 无状态
- 支持线上的cluster模式和多项目部署
II. 三步快速开始
安装
在控制台执行下面的命令安装:
npm install easy-monitor
项目中引入
在你的项目入口文件中按照如下方式引入,传入你的项目名称:
const easyMonitor = require('easy-monitor');
easyMonitor('你的项目名称');
访问监控页面
打开你的浏览器,输入以下地址,即可看到进程相关信息:
http://127.0.0.1:12333
以上三步即可开启你的专属性能监控服务,非常简单!
III. 定制化
Easy-Monitor
也为大家保留了一些重要的属性可以方便定制化,依靠执行 require('easy-monitor')(object)
函数时传入一个对象,来替代默认传入的项目名称的字符串,这个传入的对象可以包含如下属性:
-
logLevel:Number类型,默认是2,用来设置日志级别:
- 0:不输出任何日志
- 1:输出error日志
- 2:输出info日志
- 3:输出debug日志
-
appName:String类型,默认是 process.title 获取到的值,用来设置项目名称
-
httpServerPort:Numver类型,默认是 12333,用来设置监控HTTP服务器的侦听端口
-
filterFunction:函数,默认将profiling的结果中过滤掉了包含node_modules、anonymous以及路径中不包含 “/” 的系统函数,开发者可以自己编写过滤函数来找出自己想要的结果,入参和返回值:
- filePath:String类型,profiling结果函数所在的文件全路径
- funcName:String类型,pfofiling结果函数的名称
- 返回值:为true表示保留结果,false表示过滤掉
-
monitorAuth:函数,默认不鉴权,用来进行登入监控页面的鉴权,开发者可以自己编写鉴权函数,入参和返回值:
- user:String类型,为用户名
- pass:String类型,为用户键入密码
- 返回值:Promise对象实例,resolve(true)表示鉴权通过,resolve(false)或者reject表示鉴权失败
IV. 监控页面一览
1. 首页
a. 查看整个项目
如图,点击项目名称,则会对 整个项目 所有的进程进行profiling操作,这个所有进程包含:
- 单进程模式下则只有一个主进程
- cluster模式下所有的子进程
b. 查看项目下某一个子进程
如图,在cluster模式下项目会有多个子进程,点击某一个特定的pid,则只会对 此pid对应的子进程 进行profiling操作。
c. 多项目部署
如图,Easy-Monitor
支持多项目部署,用法和单项目是一模一样的,可以参考前面的快速开始。那么多项目启动后,监控页面会展示出不同的项目名称和对应的子进程pid。
2. 监控详情页
a. 执行时间超出预期的函数列表
如图,可以追加 querystring
参数的形式自定义预期时间以及展示的条数,如下:
?timeout=你预期的时间(ms)
?long_limit=你想展示的条数
?timeout=你预期的时间(ms)&long_limit=你想展示的条数
b. 耗费时间最久的函数列表
如图,可以追加 querystring
参数的形式自定义展示条数,如下:
?top_limit=你想展示的条数
c. v8引擎无法优化的函数列表
如图,可以追加 querystring
参数的形式自定义展示条数,如下:
?bail_limit=你想展示的条数
V. 测试
git clone下本代码后,使用npm安装依赖,然后执行如下测试脚本:
npm run test
即可看到覆盖率测试报告。
VI. 结语
最后项目地址为:Easy-Monitor
欢迎大家提issue,或者一起开发完善,如果感觉不错,赏个star也是很开心的事情~
不知不觉离上次写点东西又隔了一个月了,时间过得还真是快 :(
有意思
@gzhangzy 哈哈,我自己也在用,有针对性的调优函数性能
厉害了
@justjoker 嘿嘿~
保存一下
@zsea 正在打算加入线上的定位mem-leak时疑似泄漏的以及对应的对象引力图的功能,可以关注下~
可以,有机会试一下。
@hyj1991 不知道有没有提供api,用户可以整合进自己的统一监控系统。
@zsea 等这一期功能完成了考虑加入直接解析的API接口~
我改写的监控项目 https://github.com/ericjjj/pm86.git 还是要向楼主学习一个
@jkjk77 这个挺赞的哇,其实注入pm2也有考虑过,但是考虑到pm2版本更新等问题,就做成npm包子进程的形式了~
@hyj1991 楼主的 耗费时间最久的函数列表 这部分 很赞, 互相学习, 我在想 如何监控路由, 以及数据怎么存储, 尽量对 被监控项目侵入性低, 楼主有没有什么好的想法?
@jkjk77 侵入性低那就在运行时(启动子进程时)预加载你的 “侵入代码”,用来hack 底层函数,比如在 http 模块中黑掉 http.Server.protptype.on
和 http.Server.prototype.addListener
方法,当 type==='request'
时,把listener注入你的方法,那么你就能不侵入任何业务代码的情况下拦截路由、响应时间,statusCode等等了。
以此类推,express,koa框架等也可以这么黑,当然会复杂一些。
其实 oneAPM类的监控工具,能做到只在项目顶部 require 一下后做到细致的监控,原理都是这样的
@jkjk77 你注入了 pm2 模块的话,那连项目顶部 require 一下估计都不需要,直接就能用了。 我想做的其实是轻量一些的针对 node 本身的特色 性能监控,所以不保留任何历史数据,仅仅在线上项目出现阻塞、慢函数或者内存泄漏时能帮助定位到泄漏点。 所以这个项目打算只针对线上运行时提供两个功能了:
- cpu类函数性能调优指南
- memory类疑似泄漏点排查
咨询一下,按照你教程所讲。安装并引入了包。使用node命令启动程序时候,报出夜莺成功连接127.0.0.1:26666 success 但我在谷歌浏览器打开连接 http://127.0.0.1:12333 时候,提示拒绝连接请求。这是我的projectname 处出现问题了么? /path/projectA/bin/main.js 以这路径为例,我的project name直接写projectA这样可以么? @hyj1991
是的,当时自己糊涂啦。后来才发现这个问题。谢谢你啦。