root@aea87fa6e6a2:/home/node# cat login2.js

const request = require('request-promise');
const moment = require('moment');
const cron = require('node-cron'); process.env.TZ = 'Asia/Shanghai'; // 设置时区为上海时区
const rp = require('request-promise');
// 三台服务器地址、用户名和密码数组
const nTime=30;
const servers = [
{ ip: '192.168.0.4', username: '0463511', password: 'i@123456' },
{ ip: '192.168.0.95', username: '0721702', password: '123456' },
{ ip: '192.168.0.196', username: '1820318', password: '123456' }
]; // 登录链接
const loginUrl = 'http://{{server}}/api/auth/login'; // {{server}} 是占位符,将 在每次迭代中替换为服务器地址
// 数据采集链接
const dataUrl = 'http://{{server}}/api/icsp/scheduleLog/page?page=1&limit=10'; // 定时器间隔(以毫秒为单位)
const interval = 60000; // 循环检测主函数
async function loopCheck() {
for (const server of servers) {
try {
serverIP=server.ip;
// 构建当前服务器的登录链接
const currentLoginUrl = loginUrl.replace('{{server}}', server.ip);
// 构建当前服务器的数据采集链接
const currentDataUrl = dataUrl.replace('{{server}}', server.ip); // 发送登录请求
const response = await request.post({
url: currentLoginUrl,
json: true,
body: {
userName: server.username,
password: server.password
}
}); // 登录成功则输出信息
if (response.statusCode === 200) {
console.log(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] 登录服 务器 ${server.ip} 成功`); // 获取登录凭证(token)
const token = response.data.token; // 使用获取的 token 发起数据采集请求
await dataRequest(currentDataUrl, token,server.ip);
} else {
console.error(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] 登录 服务器 ${server.ip} 失败:`, response.message);
}
} catch (error) {
console.error(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] 登录服务 器 ${server.ip} 失败:`, error.message);
}
await sleep(3000);//服务器间的检测间隔
} // 检测完所有服务器后,等待一段时间后再次执行循环检测
// setTimeout(loopCheck, interval); //这里是循环检测入口
} async function loopCheck_info() {
for (const server of servers) {
try {
serverIP=server.ip;
// 构建当前服务器的登录链接
const currentLoginUrl = loginUrl.replace('{{server}}', server.ip);
// 构建当前服务器的数据采集链接
const currentDataUrl = dataUrl.replace('{{server}}', server.ip); // 发送登录请求
const response = await request.post({
url: currentLoginUrl,
json: true,
body: {
userName: server.username,
password: server.password
}
}); // 登录成功则输出信息
if (response.statusCode === 200) {
console.log(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] 登录服 务器 ${server.ip} 成功`); // 获取登录凭证(token)
const token = response.data.token; // 使用获取的 token 发起数据采集请求
await dataRequest_info(currentDataUrl, token,server.ip);
} else {
console.error(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] 登录 服务器 ${server.ip} 失败:`, response.message);
}
} catch (error) {
console.error(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] 登录服务 器 ${server.ip} 失败:`, error.message);
}
await sleep(3000);//服务器间的检测间隔
} // 检测完所有服务器后,等待一段时间后再次执行循环检测
// setTimeout(loopCheck, interval); //这里是循环检测入口
} // 数据请求
async function dataRequest(dataUrl, token,serverIP) {
// 构建请求头,包含 token
const headers = {
'Authorization': token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}; // 发送数据采集请求
const response = await request({
url: dataUrl,
method: 'GET',
headers: headers
}); // 解析数据
dataParse(response);
} // 数据请求2
async function dataRequest_info(dataUrl, token,serverIP) {
// 构建请求头,包含 token
const headers = {
'Authorization': token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}; // 发送数据采集请求
const response = await request({
url: dataUrl,
method: 'GET',
headers: headers
}); // 解析数据
dataParse_info(response);
} // 解析数据
async function dataParse(response) {
// 检查响应体是否为空
if (!response) {
console.error('Received empty response body.');
return;
} // 解析 JSON 数据
const jsonData = JSON.parse(response); // 获取数据数组
const rows = jsonData.data.rows; // 标志,表示是否找到了符合条件的条目
let found = false; // 遍历数据数组,查找状态为"数据同步任务运行中"的条目
for (const rowData of rows) {
// 如果状态为"数据同步任务运行中",则打印对应的时间
if (rowData.error === "数据同步任务运行中...") {
found = true;//检测运行变量
//updateTime是最后更新时间,createTime是创建时间。这里用更新时间
const createTime = moment(rowData.updateTime, 'YYYY-MM-DD HH:mm:ss').toDate();
const currentTime = new Date();
const minutesDifference = (currentTime.getTime() - createTime.getTime()) / (1000 * 60); // 如果时间差超过1小时,则打印超时信息
if (minutesDifference > nTime) {
console.log('脚本监测到系统超时');
console.log('超时时间:', minutesDifference.toFixed(0), '分钟');
await sendLogsToAPI(`${moment().format('YYYY-MM-DD HH:mm:ss')} \nAEO ${serverIP} 异常 \n状态超时: ${minutesDifference.toFixed(0)}分钟` ); } console.log('时间:', rowData.updateTime);
await sleep(1000);
break; // 找到符合条件的条目后直接跳出循环
}
} // 如果未找到符合条件的条目,则输出提示信息
if (!found) {
console.log('未找到符合条件的条目');
await sendLogsToAPI(`${moment().format('YYYY-MM-DD HH:mm:ss')} \nAEO ${serverIP} 异常 \n进程没有运行` );
}
} // 解析数据
async function dataParse_info(response) {
// 检查响应体是否为空
if (!response) {
console.error('Received empty response body.');
return;
} // 解析 JSON 数据
const jsonData = JSON.parse(response); // 获取数据数组
const rows = jsonData.data.rows; // 标志,表示是否找到了符合条件的条目
let found = false; // 遍历数据数组,查找状态为"数据同步任务运行中"的条目
for (const rowData of rows) {
// 如果状态为"数据同步任务运行中",则打印对应的时间
if (rowData.error === "数据同步任务运行中...") {
found = true;//检测运行变量
//updateTime是最后更新时间,createTime是创建时间。这里用更新时间
const createTime = moment(rowData.updateTime, 'YYYY-MM-DD HH:mm:ss').toDate();
const currentTime = new Date();
const minutesDifference = (currentTime.getTime() - createTime.getTime()) / (1000 * 60); // 如果时间差超过1小时,则打印超时信息
if (minutesDifference > nTime) {
console.log('脚本监测到系统超时');
console.log('超时时间:', minutesDifference.toFixed(0), '分钟');
await sendLogsToAPI(`${moment().format('YYYY-MM-DD HH:mm:ss')} \nAEO ${serverIP} 异常 \n状态超时: ${minutesDifference.toFixed(0)}分钟`); }else{
console.log('正常运行中');
await sendLogsToAPI(`${moment().format('YYYY-MM-DD HH:mm:ss')} \nAEO ${serverIP} 正常 \n最后更新: ${minutesDifference.toFixed(0)}分钟前`); } console.log('时间:', rowData.updateTime);
await sleep(1000);
break; // 找到符合条件的条目后直接跳出循环
}
} // 如果未找到符合条件的条目,则输出提示信息
if (!found) {
console.log('未找到符合条件的条目');
await sendLogsToAPI(`${moment().format('YYYY-MM-DD HH:mm:ss')} \nAEO ${serverIP} 异常 \n进程没有运行` );
}
} const sendLogsToAPI = (logs) => {
const resData = {
"msgtype": "text",
"text": {
"content": logs,
}
}; const options = {
method: "POST",
uri: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=17e3b586-20b3-eca2ffa84130",
// uri: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=8ff711ab-f80b-4874-7adf0831a8bc",
headers: {
"content-type": "application/json",
},
body:JSON.stringify(resData),
}; try {
const response = rp(options);
console.log('提示成功!');
} catch (error) {
console.error('请求出错:', error);
}
}; // 休眠函数
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
} // 开始循环检测
//loopCheck(); // 在每分钟的第 30 秒执行目标函数
cron.schedule('35 8 * * *', () => {
console.log('目标函数在8:35执行!');
loopCheck_info();
// 在这里调用你想要定时执行的函数
}); cron.schedule('*/30 9-20 * * *', () => {
console.log('目标函数在每分钟的第 50分钟执行!');
loopCheck();
// 在这里调用你想要定时执行的函数
});

NODEJS通过发送json数据查询目标服务,实现服务器状态监控,发现异常发送到微信群提醒的更多相关文章

  1. python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)

    昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...

  2. Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件

    一.Django与Ajax AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻 ...

  3. ajax 发送json数据时为什么需要设置contentType: "application/json”

    1. ajax发送json数据时设置contentType: "application/json”和不设置时到底有什么区别? contentType: "application/j ...

  4. ajax发送json数据时为什么需要设置contentType: "application/json”

    1. ajax发送json数据时设置contentType: "application/json”和不设置时到底有什么区别?contentType: "application/js ...

  5. Django中数据传输编码格式、ajax发送json数据、ajax发送文件、django序列化组件、ajax结合sweetalert做二次弹窗、批量增加数据

    前后端传输数据的编码格式(contentType) 提交post请求的两种方式: form表单 ajax请求 前后端传输数据的编码格式 urlencoded formdata(form表单里的) ja ...

  6. SpringMVC客户端发送json数据时报400错误

    当测试客户端发送json数据给服务器时,找不到响应路径? 原来是参数类型不符,即使是json也要考虑参数的个数和类型 解决:将age请求参数由"udf"改为"3" ...

  7. iOS开发网络篇—发送json数据给服务器以及多值参数

    iOS开发网络篇—发送json数据给服务器以及多值参数 一.发送JSON数据给服务器 发送JSON数据给服务器的步骤: (1)一定要使用POST请求 (2)设置请求头 (3)设置JSON数据为请求体 ...

  8. 【转】iOS开发网络篇—发送json数据给服务器以及多值参数

    原文: http://www.cnblogs.com/wendingding/p/3950132.html 一.发送JSON数据给服务器 发送JSON数据给服务器的步骤: (1)一定要使用POST请求 ...

  9. perl post发送json数据

    sub  wx_init {                #$login_url ="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=- ...

  10. JSON的简单使用_向前台发送JSON数据

    转自:http://www.cnblogs.com/digdeep/p/5574366.html 1.前台页面 <%@ page language="java" conten ...

随机推荐

  1. C++ 运算符全解析:从基础概念到实际应用

    C++ 运算符 运算符用于对变量和值执行操作. 在下面的示例中,我们使用 + 运算符将两个值相加: int x = 100 + 50; 虽然 + 运算符经常用于将两个值相加,就像上面的示例一样,但它也 ...

  2. 深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓

    在本文中,我们将介绍 IoC(控制反转)和 DI(依赖注入)的概念,以及如何在 Spring 框架中实现它们. 什么是控制反转? 控制反转是软件工程中的一个原则,它将对象或程序的某些部分的控制权转移给 ...

  3. Nacos 多个实例的服务调用失败

    在微服务开发阶段,开发人员会频繁启动服务. 这样Nacos上会经常出现一个服务存在多个实例,这是自己和其他同事都启动了同一个服务造成的. 此时使用OpenFeign对该服务进行远程调用,会有很大概率出 ...

  4. Qt调用摄像头二,Pro版

    本示例,为纯Qt调用摄像头,功能会比版本一要多一点:打开摄像头,设置参数,完整拍照,框选拍照,切换分辨率,旋转,水平镜像,垂直镜像,放大,缩小 上一个版本,使用的显示窗口直接显示出摄像头画面,所以可操 ...

  5. HarmonyOS 设备管理开发:USB 服务开发指导

      基本概念 USB服务是应用访问底层的一种设备抽象概念.开发者根据提供的USB API,可以获取设备列表.控制设备访问权限.以及与连接的设备进行数据传输.控制命令传输等. 运作机制 USB服务系统包 ...

  6. Harbor高可用集群设计及部署(基于离线安装方式)

    原文转自:Harbor高可用集群设计及部署(基于离线安装方式) 架构至美 2022-09-05 09:28 发表于北京 编者荐语: 纯干货.实用,推荐系数5颗星. 以下文章来源于Harbor进阶实战  ...

  7. 面试官:说一说CyclicBarrier的妙用!我:这个没用过

    写在开头 面试官:同学,AQS的原理知道吗? 我:学过一点,抽象队列同步器,Java中很多同步工具都是基于它的... 面试官:好的,那其中CyclicBarrier学过吗?讲一讲它的妙用吧 我:啊,这 ...

  8. 向量数据库之Lancedb学习记录

    简介 Lancedb是一个用于人工智能的开源矢量数据库,旨在存储.管理.查询和检索大规模多模式数据的嵌入.Lancedb的核心是用Rust编写的,并构建在Lance之上,专为高性能 ML 工作负载和快 ...

  9. element-ui多选(批量)删除

    导出axios请求

  10. WebRTC获取IP地址问题,Uncaught TypeError: Cannot read property '1' of null

    WebRTC获取IP地址问题,Uncaught TypeError: Cannot read property '1' of null 临时接了个任务,客户要求某个账号只能在某个ip或者mac上登录, ...