UNPKG

cna-monitor

Version:

监控域名/IP地址是否可达,并记录可访问性

447 lines (415 loc) 15.7 kB
#!/usr/bin/env node const readlineSync = require('readline-sync'); const fs = require('fs'); const _comm = require('./lib/comm'); const path = require('path'); const configFile = path.join(__dirname, './config/config'); const portFile = path.join(__dirname, './config/port'); const emailFile = path.join(__dirname, './config/email'); const args = _comm.convertArgs(); const defaultConfig = require('./default/config'); const emailComm = require('./lib/email'); args.debug && console.log("目前运行目录:", path.join(__dirname, './')); args.debug && console.log("输入参数:", args); require('./lib/proto/string'); require('./lib/proto/date'); let config; if (fs.existsSync(configFile)) { config = JSON.parse(fs.readFileSync(configFile).toString().decrypt()); } else { config = defaultConfig; } args.debug && console.log("配置信息:", config); const outFile = path.join(__dirname, './out/result'); const keysFile = path.join(__dirname, './config/keys'); const slog = require('single-line-log').stdout; const log = require('./lib/log'); const os = require('os'); log.info("运行命令:", args); if (args.help) { _comm.help(args); } else if (args.version) { _comm.version(); } else if (args.logs) { try { if (args.export && args.export !== true) { _comm.zip(path.join(__dirname, './logs/'), args.export); } else if (args.f) { const logFile = path.join(__dirname, './logs/' + new Date().format('yyyyMMdd') + '.log'); if (fs.existsSync(logFile)) { //监听器回调有两个参数 (eventType, filename)。 eventType 是 'rename' 或 'change',filename 是触发事件的文件的名称。 fs.watch(logFile, function (eventType, filename) { if (eventType == 'change') { let _text = []; slog.clear(); text = fs.readFileSync(logFile).toString().split(os.EOL); let start = text.length - 200; if (start < 0) { start = 0; } for (let i = start; i < text.length; i++) { _text.push(text[i]); } slog(_text.join('\r\n')); } }); } } else if (args.s) { const logPath = path.join(__dirname, './logs/' + args.s); if (!fs.existsSync(logPath)) { console.info("指定的日志文件不存在"); return; } const result = fs.readFileSync(logPath).toString().split(os.EOL); // slog(text.join('\r\n')); let pageIndex = 1, startIndex = 0, endIndex = 0; let pageSize = args.p || config.p || 10; if (result.length <= pageSize) { for (const r of result) { console.info(r); } } else { let totalPage = parseInt(result.length / pageSize); if (result.length % pageSize) { totalPage++; } let isEnd = showText(result, pageIndex, pageSize); while (!isEnd) { readlineSync.question(` ---------- MORE (${pageIndex}/${totalPage}) ----------`); pageIndex++; isEnd = showText(result, pageIndex, pageSize); } process.exit(); } } else if (args.l) { const logs = []; const logPath = path.join(__dirname, './logs/'); if (fs.existsSync(logPath)) { fs.readdirSync(logPath).forEach(function (file) { if (file.endsWith('.log')) { const stat = fs.statSync(logPath + file); logs.push(`${file}\t${stat.mtime.format()}\t${_comm.sizeFormat(stat.size, true)}`); } }); } console.info(logs.join('\r\n')); } else if (args.clear) { const logPath = path.join(__dirname, './logs/'); if (fs.existsSync(logPath)) { fs.readdirSync(logPath).forEach(function (file) { var curPath = logPath + "/" + file; if (curPath.endsWith('.log')) { fs.unlinkSync(curPath); } }); } console.info('日志清理完成'); } } catch (e) { console.info("操作失败"); args.debug && console.warn("操作失败", e); log.error("log命令操作失败", e); } } else if (args.docker) { const portHelp = require('./lib/port'); if (!fs.existsSync(portFile)) { portHelp.getRandomUnUsePort().then(function (port) { log.info("随机未使用端口号", port); fs.writeFileSync(portFile, port.toString().encrypt()); createListen(port); }); } else { const port = parseInt(fs.readFileSync(portFile).toString().decrypt()); log.info("上次端口号", port); portHelp.checkPortIsUsed(port).then(function (isUsed) { if (!isUsed) { log.info("端口号未被占用"); createListen(port); } else { log.warn("端口号已被占用,说明正在监听,无需操作"); } }); } } else if (args.backup) { _comm.backup(args); } else if (args.import) { _comm.import(args); } else if (args.config) { _comm.config(args); } else if (args.init) { const pid = _comm.checkProcess(); let answer; if (pid) { answer = readlineSync.question(`监控程序正在运行,初始化会停止并清空所有记录,是否继续(y/n)?`); } else { answer = readlineSync.question(`初始化会清空所有记录,是否继续(y/n)?`); } if (answer.toLowerCase() == 'y') { console.info("开始执行初始化..."); _comm.init(args); console.info("初始化完成"); } } else if (args.keys) { const keys = _comm.keys(); for (const k of keys) { console.info(k); } } else if (args.upgrade) { _comm.upgrade(); } else if (args.restart) { _comm.stop(); _comm.start(); console.info(`监控程序重启完成!`); process.exit(1); } else if (args.start) { _comm.start(); process.exit(1); } else if (args.stop) { _comm.stop(); } else if (args.status) { _comm.status(); } else if (args.add) { try { _comm.add(args.ip || "", args.name || ""); const answer = readlineSync.question(`添加【目标:${args.ip || ""}${args.name ? `(别名:${args.name})` : ""}】成功,是否重启监控程序(y/n)?`); if (answer.toLowerCase() == 'y') { _comm.stop(); _comm.start(); console.info(`监控程序重启完成!`); process.exit(1); } } catch (e) { console.warn('添加失败'); args.debug && console.error(e); log.warn('添加失败:', e); } } else if (args.delete) { try { _comm.delete(args.ip || ""); const answer = readlineSync.question(`删除【目标:${args.ip || ""}】成功,是否重启监控程序(y/n)?`); if (answer.toLowerCase() == 'y') { _comm.stop(); _comm.start(); console.info(`监控程序重启完成!`); process.exit(1); } } catch (e) { console.warn('删除失败'); args.debug && console.error(e); log.warn('删除失败:', e); } } else if (args.remove) { try { _comm.stop(); if (fs.existsSync(keysFile)) { fs.unlinkSync(keysFile); } console.info(`清空监听目标完成!`); } catch (e) { console.warn('清空监听目标失败'); args.debug && console.error(e); log.error("清空监听目标失败", e); } } else if (args.email) { try { if (args.l) { if (fs.existsSync(emailFile)) { const emailConfig = JSON.parse(fs.readFileSync(emailFile).toString().decrypt()); console.info(`已配置发送邮件服务器:`); console.info(`SMTP服务器:`, emailConfig.host); console.info(`SMTP服务器端口:`, emailConfig.port); console.info(`是否SSL:`, emailConfig.secure); console.info(`账号:`, emailConfig.user); console.info(`密码:********`); } else { console.info(`未配置发送邮件服务器`); } } else if (args.clear) { if (fs.existsSync(emailFile)) { fs.unlinkSync(emailFile); } console.info(`清空发送邮件服务器配置完成`); } else if (args.try) { if (!fs.existsSync(emailFile)) { console.info(`未配置发送邮件服务器`); } else { if (!config.n) { console.info(`未配置邮件收件人`); } else { const emailConfig = JSON.parse(fs.readFileSync(emailFile).toString().decrypt()); const emailHelp = new emailComm(emailConfig); // const emailRes = await emailHelp.send(config.n, `监听测试邮件`, ``); // console.info(`已经尝试发送邮件:`, emailRes); endMailTestSend(emailHelp).then(function (emailRes) { console.info(`已经尝试发送邮件给${config.n}:`, emailRes); }).catch(function (e) { log.error(e); console.info(`尝试发送测试邮件失败`); }); } } } else { _comm.email(args); console.info(`设置email通知成功`); } } catch (e) { console.warn('邮件服务器连接失败'); args.debug && console.error(e); log.error('设置email通知失败', e); } } else if (args.list) { console.info("时间\t目标\t别名\t状态\t输出"); if (args.f) { try { if (fs.existsSync(outFile)) { let _keys = []; if (fs.existsSync(keysFile)) { _keys = JSON.parse(fs.readFileSync(keysFile).toString().decrypt()); } let text = fs.readFileSync(outFile).toString().split('\r\n'); let maxLen = _keys.length * 2; maxLen = maxLen < config.p ? config.p : maxLen; if (maxLen > text.length) { maxLen = text.length; } let _text = []; for (let i = maxLen - 1; i >= 0; i--) { try { let tmp = JSON.parse(text[i].decrypt()); _text.push(`${tmp.time}\t${tmp.target}\t${tmp.alias}\t${tmp.status}\t${tmp.message || ""}`); } catch (e) { } } slog(_text.join('\r\n')); //监听器回调有两个参数 (eventType, filename)。 eventType 是 'rename' 或 'change',filename 是触发事件的文件的名称。 fs.watch(outFile, function (eventType, filename) { if (eventType == 'change') { slog.clear(); text = fs.readFileSync(outFile).toString().split('\r\n'); maxLen = _keys.length * 2; maxLen = maxLen < config.p ? config.p : maxLen; if (maxLen > text.length) { maxLen = text.length; } let _text = []; for (let i = maxLen; i >= 0; i--) { try { let tmp = JSON.parse(text[i].decrypt()); _text.push(`${tmp.time}\t${tmp.target}\t${tmp.alias}\t${tmp.status}\t${tmp.message || ""}`); } catch (e) { } } slog(_text.join('\r\n')); } }); } else { console.warn(`目标状态记录不存在,请稍后再试`); process.exit(); } } catch (e) { console.warn(`监听异常`); args.debug && console.error(e); log.error('监听异常', e); process.exit(); } } else { let result = _comm.list(); if (args.t) { result = result.filter(item => item.target == args.t || item.alias == args.t); } let pageIndex = 1, startIndex = 0, endIndex = 0; let pageSize = args.p || config.p || 10; if (result.length <= pageSize) { for (const r of result) { console.info(`${r.time}\t${r.target}\t${r.alias}\t${r.status}\t${r.message || ""}`); } } else { let totalPage = parseInt(result.length / pageSize); if (result.length % pageSize) { totalPage++; } let isEnd = show(result, pageIndex, pageSize); while (!isEnd) { readlineSync.question(` ---------- MORE (${pageIndex}/${totalPage}) ----------`); pageIndex++; isEnd = show(result, pageIndex, pageSize); } process.exit(); } } } else { log.info("运行不存在的命令", args); console.warn('请使用"cna-monitor help"查看启动帮助'); process.exit(); } function show(result, pageIndex, pageSize) { let isEnd = false; startIndex = (pageIndex - 1) * pageSize; endIndex = pageIndex * pageSize - 1; if (endIndex >= result.length) { endIndex = result.length - 1; isEnd = true; } for (let i = startIndex; i <= endIndex; i++) { console.info(`${result[i].time}\t${result[i].target}\t${result[i].alias}\t${result[i].status}\t${result[i].message || ""}`); } return isEnd; } function showText(result, pageIndex, pageSize) { let isEnd = false; startIndex = (pageIndex - 1) * pageSize; endIndex = pageIndex * pageSize - 1; if (endIndex >= result.length) { endIndex = result.length - 1; isEnd = true; } for (let i = startIndex; i <= endIndex; i++) { console.info(result[i]); } return isEnd; } function createListen(port) { const server = require('http').createServer(); if (args.debug) { server.on('listening', function () { log.info(`docker环境为了防止自动停止,需要一直监听(${server.address().port})`); }); } server.listen(port); } function endMailTestSend(emailHelp) { return new Promise(async function (resolve, reject) { try { // const res = []; // config.n = config.n.split(';'); // for (const n of config.n) { // if (n) { // const emailRes = await emailHelp.send(n, `监听测试邮件`, ``); // res.push(n); // } // } const res = await emailHelp.send(config.n, `监听测试邮件`, ``); resolve(res); } catch (e) { reject(e); } }); }