'use strict'; const moment = require('moment'); const diskinfo = require('diskinfo'); const os = require('os-utils'); const request = require("superagent"); function getNodeResources(opts) { return async function (ctx, next) { let errMsg = { message: '获取节点资源失败' } try { //获取系统内存情况 let freeMem = os.freemem() let totalMem = os.totalmem() let memory = Math.round(((totalMem - freeMem) / totalMem) * 1000) / 10 //cpu利用率 let cpuUsage = await getCPUUsage() //硬盘占用率数据 let disk = await getDiskInfo(); ctx.status = 200; ctx.body = { disk, memory, cpu: Math.round(cpuUsage * 1000) / 10 }; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = errMsg } } } /** * 获取硬盘信息 */ async function getDiskInfo() { return new Promise(function (resolve, reject) { diskinfo.getDrives((err, aDrives) => { let map = new Map() //遍历所有磁盘信息 let total = 0, used = 0; for (var i = 0; i < aDrives.length; i++) { if (!map.has(aDrives[i].mounted)) { map.set(aDrives[i].mounted, true) total += aDrives[i].blocks; //总量 used += aDrives[i].used; //已使用 } } let rate = Math.round(used / total * 1000) / 10 resolve(rate); }); }); } /** * 获取系统cpu利用率 */ async function getCPUUsage() { return new Promise((resolve, reject) => { os.cpuUsage(function (v) { resolve(v) }); }); } //查询后端同步数据库数据量总量和top5 function getDataTotalTop5(opts) { return async function (ctx, next) { const models = ctx.fs.dc.models; try { let total = await models.DbStatistics.sum('dbRecordCount') let top5 = await models.DbStatistics.findAll({ order: [["dbRecordCount", "desc"]], limit: 5, offset: 0, include: [{ model: models.DataSource, include: [ { model: models.ResourceCatalog, attributes: ['id', 'name'], }] }], }) ctx.status = 200; ctx.body = { total, top5 }; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '查询后端同步数据库数据量总量和top5' } } } } async function queryToken_(ctx) { let rslt = null; try { const { k8s } = ctx; const params = { grant_type: 'password', username: 'admin', password: 'Fashion123', client_id: 'kubesphere', client_secret: 'kubesphere', } const url = k8s + '/oauth/token' rslt = await request.post(url).send(params) .set('Content-Type', 'application/x-www-form-urlencoded') return (rslt || {}).body || null; } catch (err) { throw err } } function mathRound(use, total) { return Math.round(parseFloat(use) / parseFloat(total) * 1000) / 10 } function getClusterInfo(opts) { return async function (ctx, next) { const { k8s } = opts; let errMsg = { message: '获取节点资源失败' } try { const token = await queryToken_(opts); const url = k8s + '/kapis/monitoring.kubesphere.io/v1alpha3/cluster?metrics_filter=cluster_cpu_usage%7Ccluster_cpu_total%7Ccluster_memory_usage_wo_cache%7Ccluster_memory_total%7Ccluster_disk_size_usage%7Ccluster_disk_size_capacity%7Ccluster_pod_running_count%7Ccluster_pod_quota%24' let res = await request.get(url) .set('Authorization', `Bearer ${token.access_token}`) .set('Content-Type', 'application/json;charset=utf-8'); if (res.body && res.body.results) { let results = res.body.results; let cpuUsage = ((results.find(s => s.metric_name == 'cluster_cpu_usage') || {}).data || {}).result[0].value[1]; let cpuTotal = ((results.find(s => s.metric_name == 'cluster_cpu_total') || {}).data || {}).result[0].value[1]; let diskUsage = ((results.find(s => s.metric_name == 'cluster_disk_size_usage') || {}).data || {}).result[0].value[1]; let diskTotal = ((results.find(s => s.metric_name == 'cluster_disk_size_capacity') || {}).data || {}).result[0].value[1]; let memoryUsage = ((results.find(s => s.metric_name == 'cluster_memory_usage_wo_cache') || {}).data || {}).result[0].value[1]; let memoryTotal = ((results.find(s => s.metric_name == 'cluster_memory_total') || {}).data || {}).result[0].value[1]; ctx.status = 200; ctx.body = { cpu: mathRound(cpuUsage, cpuTotal), disk: mathRound(diskUsage, diskTotal), memory: mathRound(memoryUsage, memoryTotal), }; } else { ctx.status = 400; ctx.body = errMsg; } } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = errMsg } } } function getRestfulInfo(opts) { return async function (ctx, next) { const models = ctx.fs.dc.models; try { const Op = ctx.fs.dc.ORM.Op; let allApis = await models.RestfulApiRecord.findAndCount({ order: [["id", "desc"]], where: { id: { [Op.gt]: 0 } }, include: [ { model: models.RestfulApi, }] }) let top3Obj = {} allApis.rows.map(s => { if (top3Obj[s.restServiceId]) { top3Obj[s.restServiceId] = { ...top3Obj[s.restServiceId], count: top3Obj[s.restServiceId].count + 1 } } else { top3Obj[s.restServiceId] = { count: 1, name: s.restfulApi.name } } }) let top3Arr = [] Object.keys(top3Obj).map(key => { top3Arr.push({ id: key, name: top3Obj[key].name, count: top3Obj[key].count }) }) let total = allApis.count; let todayArr = allApis.rows.filter(s => moment().startOf('d') < moment(s.visitTime) && moment().endOf('d') > moment(s.visitTime)) let todayUser = Array.from(new Set(todayArr.map(s => s.token))) let totalUser = Array.from(new Set(allApis.rows.map(s => s.token))) ctx.status = 200; ctx.body = { total, //接口访问总次数 todayTotal: todayArr.length, //今日访问次数 todayUser: todayUser.length, //今日访问用户数 totalUser: totalUser.length,//接口访问用户总数 top3: top3Arr.sort((a, b) => b.count - a.count).slice(0, 3),//接口访问次数top3 }; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '获取restful统计信息失败' } } } } function getQualityCheckAlarm(opts) { return async function (ctx, next) { const models = ctx.fs.dc.models; try { let alarms = await models.QualityCheckAlarm.findAll({}) ctx.status = 200; ctx.body = alarms; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '获取预警列表失败' } } } } module.exports = { getNodeResources, getDataTotalTop5, getClusterInfo, getRestfulInfo, getQualityCheckAlarm }