nodejs PM2监控及报警邮件发送(二)
前言
用过nodejs都知道PM2,这章主要讲讲PM2监控程序及报警邮件
用pm2 启动app后,app挂掉自动拉起,但是维护人员不知道啊,所以需要其他方式通过(如邮件)
1:环境
centos7
node14
2: 安装nodejs 及 pm2
1: node安装 (以node-v14.17.3-linux-x64为例) 版本自行选择
1>下载 node-v14.17.3-linux-x64.tar.xz 网上自行去搜
路径: /home/node-v14.17.3-linux-x64.tar.xz
2>解压缩
xz -d node-v14.17.3-linux-x64.tar.xz
tar -xf node-v14.17.3-linux-x64.tar
3>创建软链接
ln -s /home/node-v14.17.3-linux-x64/bin/npm /usr/bin/npm
ln -s /home/node-v14.17.3-linux-x64/bin/node /usr/bin/node
4>测试
node -v
2: 安装pm2
1> npm install -g pm2 //全局安装
安装完 如下
[root@VM-22-234-centos nodejsserver0628]# npm install -g pm2
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
/home/node-v14.17.3-linux-x64/bin/pm2 -> /home/node-v14.17.3-linux-x64/lib/node_modules/pm2/bin/pm2
/home/node-v14.17.3-linux-x64/bin/pm2-dev -> /home/node-v14.17.3-linux-x64/lib/node_modules/pm2/bin/pm2-dev
/home/node-v14.17.3-linux-x64/bin/pm2-docker -> /home/node-v14.17.3-linux-x64/lib/node_modules/pm2/bin/pm2-docker
/home/node-v14.17.3-linux-x64/bin/pm2-runtime -> /home/node-v14.17.3-linux-x64/lib/node_modules/pm2/bin/pm2-runtime
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules/pm2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current:
2> 创建软连接
ln -s /home/node-v14.17.3-linux-x64/bin/pm2 /usr/bin/pm2
3>pm2 命令
$ pm2 start app.js -i 4 #后台运行pm2,启动4个app.js # 也可以把'max' 参数传递给 start# 正确的进程数目依赖于Cpu的核心数目
$ pm2 start app.js --name my-api # 命名进程
$ pm2 list # 显示所有进程状态
$ pm2 monit # 监视所有进程
$ pm2 logs # 显示所有进程日志
$ pm2 stop all # 停止所有进程
$ pm2 restart all # 重启所有进程
$ pm2 reload all # 0秒停机重载进程 (用于 NETWORKED 进程)
$ pm2 stop 0 # 停止指定的进程
$ pm2 restart 0 # 重启指定的进程
$ pm2 startup # 产生 init 脚本 保持进程活着
$ pm2 web # 运行健壮的 computer API endpoint (http://localhost:9615)
$ pm2 delete 0 # 杀死指定的进程
$ pm2 delete all # 杀死全部进程
3:监控及邮件
monit_app.js 内容如下
const pm2 = require('pm2')
//const sendmail = require('./sendmail');
function pm2checkdump(){console.log("enter pm2checkdump");pm2.connect(function(err) {if (err) {console.error(err)//process.exit(2)return }pm2.list((err, list) => {// console.log(err, list)if(err){}else{parsedata(list);}pm2.disconnect()})})
}const fs = require('fs')
const path = require('path')var mapprocess = {};
map['key1'] = 1;
//map['key2@'] = 2;//console.log(map['key1']);//结果是1.
console.log(map['key2@']);//结果是2.
var shellcount = 0 ;
var writelogcount = 0;
var monit_pid = 0 ; //监控程序的PID
var waiwang_ip = "" ; //外网IP
//如果遍历map
for(var prop in mapprocess){if(mapprocess.hasOwnProperty(prop)){console.log('key is ' + prop +' and value is' + mapprocess[prop]);}
}var exec = require('child_process').exec;function sendmailto(context){let sendermail = "sendermail@163.com" ; //发送人let receiver = "receiver1@qq.com,receiver2@qq.com"; //接收人let mailserver = "smtp.163.com:25" ; //邮箱服务器及端口let mailpw = "shouquanma123"; //授权码let cmdstr = "sendEmail -o tls=no -f " +sendermail + " -t " + receiver + " -s " + mailserver + " -xu " + sendermail +" -xp "+ mailpw + " -u " ;cmdstr = cmdstr + context ;cmdstr = cmdstr + " -m " +context ;// " '33邮件测试33' -m '33邮件正文你的错误了2'" ;exec(cmdstr ,function(error, stdout, stderr){if(error) {console.error('error: ' + error);return;}console.log('stdout: ' + stdout);});
}//查询外网IP
function queryip(){//curl ifconfig.me 返回IPlet cmdstr = "curl ip.cip.cc"; ////返回IP 加地区 curl cip.ccexec(cmdstr ,function(error, stdout, stderr){if(error) {console.error('error: ' + error);return;}//console.log('stdout: ' + stdout);waiwang_ip = ''+stdout ;console.log(waiwang_ip);});
}//测试发送邮件
function testmail(){let curtime = Date.now();let text ="["+curtime+"] "+"testmail!!";sendmailto(text) ;
}var http=require('http');
//http post
function httppost(url,port,path,jsobject){// var data = {// a: 111,
// time: Date.now()
// }if (typeof(jsobject) != 'object')){return ;}port = port || 80 ;path = path || '/' ;var dataString = JSON.stringify(jsobject) // 转换为字符串格式var option = {hostname: url,//'127.0.0.1', // 要访问的服务器的ip地址port: port,//3000, // 要访问的服务器的端口path: path,//'/xx/xx', // 请求的接口method: 'POST', // 请求方式headers: { 'Content-Type':'application/json','Content-Length':dataString.length} }var rep = http.request(option, function(res){console.log('状态码:' + res.statusCode)console.log('响应头:' + JSON.stringify(res.headers))res.setEncoding('utf8');res.on('data', (chunk) => {//console.log(`响应主体: ${chunk}`);});res.on('end', () => {//console.log('响应中已无数据');});})req.on('error', (e) => {console.error(`请求遇到问题: ${e.message}`);});req.write(dataString) // post请求携带的参数(将数据写入请求主体)req.end(); // 必须始终调用 req.end() 来表示请求的结束}function parsedata(data){try{// 异步写入数据到文件//fs.writeFile(file, JSON.stringify(data, null, 4), { encoding: 'utf8' }, err => {})let curtime = Date.now();// let riqi = Date('Y-m-d H:i:s',''+curtime);let date = new Date(curtime);let dt = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()+' '+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds()let ymr = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() ;let logfile = path.resolve(__dirname, "./log/"+ymr+"_restart.log");let tmpfile = path.resolve(__dirname, './log/pm2listlog.log')if(typeof(data) == 'object'){for (var i = 0; i < data.length; i++) {let jsonobject = data[i] ;//console.log(dt,i, jsonobject.name,jsonobject.pm2_env.restart_time); //jsonobject.pidif (mapprocess[jsonobject.name]){let curcount = mapprocess[jsonobject.name];if(jsonobject.pm2_env.restart_time > curcount){console.log("restart",jsonobject.name,curcount)mapprocess[jsonobject.name] = jsonobject.pm2_env.restart_timelet text =''+waiwang_ip+"["+curtime+"] "+jsonobject.name+" restart!";sendmailto(text) ;fs.writeFile(logfile, text, { encoding: 'utf8', flag: 'a'}, err => {})}else{console.log(dt,jsonobject.name,curcount,jsonobject.pm2_env.restart_time)}}else {//if(shellcount > 0 || jsonobject.name.indexOf("monit") < 0) {mapprocess[jsonobject.name] = jsonobject.pm2_env.restart_time ;// console.log("first save[0]",jsonobject.name,jsonobject.pm2_env.restart_time);//}console.log("first save",jsonobject.name,jsonobject.pm2_env.restart_time);}}// let newdata = JSON.stringify(data, null, 4);if((shellcount%16) == 0){let newdata = JSON.stringify(data, null, 4);newdata = ''+dt+' '+newdata ; //增加时间if(writelogcount < 24){fs.writeFile(tmpfile, newdata, { encoding: 'utf8', flag: 'a' }, err => {}) //追加}else{fs.writeFile(tmpfile, newdata, { encoding: 'utf8', flag: 'w' }, err => {}) //截断writelogcount = 0 ;}writelogcount+=1 ;}shellcount += 1; }/// var json = JSON.parse(data);}catch(e){console.log(e)}
}const timeval = 120*1000 ;// 120秒
setInterval(pm2checkdump, timeval); //启动定时器 //多少时间后再启动
console.log("setInterval setup"+timeval);
pm2checkdump(); //所以这里先启动一次
queryip() ; //查询外网IP
//testmail();
原理
通过 pm2checkdump 解析数据,记录每个app的次数,
通过对比重启次数 判定该app是否被拉起过
启动监控 pm2 start ./monit_app.js //(根据文件路径自行修改)
4: 注意 把发送人邮箱 放入白名单里,以免收不到邮件
nodejs PM2监控及报警邮件发送(二)相关推荐
- php邮件发送tp,Thinkphp5 邮件发送Thinkphp发送邮件
在项目的开发中 用户修改密码,需要发送验证码到用户邮箱, 在common.php公共文件中加入以下代码: /** * 系统邮件发送函数 * @param string $tomail 接收邮件者邮箱 ...
- nagios监控三部曲之——为什么nagios不能发送报警邮件(2)
最近我写了关于naigos监控的安装与配置的技术文档,公司运维按照我的文档部署naigos,发现不能发送报警邮件,经过我的检查,发现问题如下: 1.hosts里的配置 [root@nagios ~]# ...
- shell脚本编写监控本机内存和硬盘剩余空间,剩余内存小于 500M、根分区剩余空间小于 1000M时,发送报警邮件给 root 管理员
监控本机内存和硬盘剩余空间,剩余内存小于 500M.根分区剩余空间小于 1000M时,发送报警邮件给 root 管理员 # 创建shell脚本文件 vim free.sh #!/bin/bash di ...
- zabbix监控mysq且配置自动发送报警邮件
这里写目录标题 zabbix监控mysq且配置自动发送报警邮件 zabbix监控mysql 实验环境 创建一个目录存放mysql用户的帐号密码 将mysql用户密码配置在文件中(安全) 安装perco ...
- nagios监控mysql服务_nagios监控mysql及邮件报警
1.使用默认监控命令check_http命令+相关的参数来实现,如下: 在command.cfg添加如下关键词监控命令:check_http_word,参数解析:-I指定IP或者主机名,-u指定URL ...
- python-flask(二)集成bootstrap、集成web表单、集成邮件发送
文章目录 一.flask集成bootstrap 1. 什么是Bootstrap? 2. Flask中如何集成Bootstrap? 3. Flask-Bootstrap实现了什么? 二.Flask中集成 ...
- Linux下监控磁盘使用量并在超过阀值后自动发送报警邮件
参考博客:http://www.heminjie.com/system/linux/1923.html 最近Linux服务器磁盘使用量经常到100%,直到影响到正常服务出现故障才会去注意,做不到防患于 ...
- Zabbix监控交换机以及邮件报警配置
Zabbix监控交换机以及邮件报警配置 搭建zabbix LNMP环境 部署zabbix_server 配置zabbix 交换机开启SNMP zabbix添加交换机 自动发现 配置报警媒介 配置接收邮 ...
- linux检测磁盘 报警,linux服务器磁盘监控脚本分享(含报警邮件)
在日常的运维工作中,我们经常会对服务器的磁盘使用情况进行巡检,以防止磁盘爆满导致的业务故障. 如果能编写一个合理完善的监控脚本,当磁盘使用率达到我们设置的阀值时,就自动发送报警邮件,以便我们及时获悉到 ...
最新文章
- Java前端控制器模式
- 不会MySQL索引,面试官让回家等通知!
- 数据持久化 技术比较
- mkisofs简单定制linux iso
- STM32L1X系列GPIO运用
- Java中final和static对修饰类、方法、属性的总结
- python odoo_odoo开发学习 -- Python2 or Python3 ?
- oracle 数据库查询 COALESCE字符函数
- Android提高篇内容整理
- Python3+Selenium3自动化测试-(四)
- 分布式框架的基石之远程通信协议
- 关于电量采集芯片(库仑计)DS2781相关操作及配置
- Matlab排序函数
- 使用UOS微信桌面版协议登录,wechaty免费版web协议又可以用了
- 【单片机笔记】PWM信号与PPM信号简单理解
- Oracle数据库上机练习6
- 用qt 编译qt moc
- Serial Programming Guide for POSIX Operating Systems(转)
- Win10装系统及科研常用软件
- 在html中引入谷歌地图