UNPKG

@opengis/fastify-table

Version:

core-plugins

154 lines (153 loc) 5.96 kB
import os from "os"; import process from "process"; import util from "node:util"; import { exec } from "node:child_process"; import { config, getFolder, pgClients, getRedis } from "../../../utils.js"; const execAsync = util.promisify(exec); const platform = os.platform(); const processFolder = os.homedir(); const formatMemoryUsage = (data) => `${(data / 1024 / 1024).toFixed(2)} MB`; const rclient = getRedis(); const rclient2 = getRedis({ db: 2 }); // const rclient10 = getRedis({ db: 10 }); const filesFolder = getFolder(config); const redisKey = "logger-process-online"; const sqlQuery = `select datname as dbname, application_name as app, client_addr as client_ip, (now()-backend_start)::text as msec, state, query from pg_stat_activity where datname=$1`; const prev = {}; const cpuUsage = () => { const usage = process.cpuUsage(); const cpus = os.cpus(); const total = cpus.reduce((acc, curr) => acc + Object.values(curr.times).reduce((a, b) => a + b, 0), 0); if (!prev.usage || !prev.total) { Object.assign(prev, { usage, total }); return 0; } const diffUsage = (usage.user - prev.usage.user + usage.system - prev.usage.system) / 1000; const diffTotal = total - prev.total; Object.assign(prev, { usage, total }); return (diffUsage / diffTotal) * cpus.length * 100; }; cpuUsage(); export default async function loggerSystem(req) { const { pg = pgClients.client } = req || {}; const dbName = pg?.options?.database; const dbsize = config.redis ? await rclient.get(`${dbName}:content:dbsize:${redisKey}`) : null; const dbVerion = pg?.query ? await pg .query("select version();") .then((el) => el.rows?.[0]?.version) : null; const dbSize = dbsize || (pg?.query ? await pg .query(`select pg_size_pretty(pg_database_size($1))`, [dbName]) .then((el) => el.rows?.[0]?.pg_size_pretty) : null); const query = pg?.query ? await pg.query(sqlQuery, [dbName]).then((el) => el.rows || []) : null; const { stdout: topProcess } = platform === "win32" ? { stdout: "Cant show top on this system type" } : await execAsync("top -b -n 1"); const osInfo = `${os.version()} ${os.machine?.() || ""}`; const cpuInfo = os.cpus(); const totalMemory = os.totalmem(); const memory = process.memoryUsage(); const resource = process.resourceUsage(); const currentCpuUsage = cpuUsage(); const redisInfo = config.redis ? await rclient.info() : ""; const lines = redisInfo.split("\r\n").filter((el) => el && el.split); const redis = {}; for (let i = 0; i < lines.length; i += 1) { const [key, val] = lines[i].split(":"); if (val) { redis[key] = val; } } if (config.redis) { await rclient.set(`${dbName}:content:dbsize:${redisKey}`, dbSize, "EX", 30 * 60); } const latency = config.redis ? await rclient.latency("latest") : null; const uptime = pg?.query ? await pg .query("select extract('epoch' from current_timestamp - pg_postmaster_start_time())::int as uptime") .then((el) => el.rows?.[0]?.uptime) : null; const metric5 = config.redis ? await rclient2.hgetall(`${dbName}:system_metrics`) : {}; Object.keys(metric5 || {}) .filter((el) => el.startsWith("time")) .forEach((m) => { metric5[m] /= 1000.0; }); const metricSort = metric5 ? JSON.parse(JSON.stringify(metric5, Object.keys(metric5).sort())) : undefined; const userOnline = config.redis ? await rclient2.scan([ "0", "match", `session_auth:${dbName}:*`, "count", "10000", ]) : []; // const userOnline = await rclient10.scan(['0', 'match', 'sess:*', 'count', '10000']); const uptimes = { "uptime:node": Math.round(process.uptime()), "uptime:system": os.uptime(), "uptime:pg": uptime, "uptime:redis": typeof redis?.uptime_in_seconds === "number" ? redis.uptime_in_seconds - 0 : 0, }; return { process: { root: process.cwd(), processFolder, saveDirectory: filesFolder, dbhost: pg?.options?.host, dbport: pg?.options?.port, dbname: dbName, }, uptimes, metric: { cpu: `${Math.round(currentCpuUsage)} %`, memory: `${Math.round((memory.rss / totalMemory) * 100 * 100) / 100} %`, "user.online": userOnline?.[1]?.length, "node.total": formatMemoryUsage(memory.heapTotal), "node.used": formatMemoryUsage(memory.heapUsed), "node.rss": formatMemoryUsage(memory.rss), "node.cpu.time": resource.systemCPUTime, "node.cpu.load": os.loadavg()[0], "redis.ram": redis.used_memory_human, "redis.latency": latency?.join?.(","), "redis.ram.peak": redis.used_memory_peak_human, "redis.clients": redis.connected_clients, "redis.db0": redis.db0?.split(",")?.[0]?.substring(5), "redis.db1": redis.db1?.split(",")?.[0]?.substring(5), "redis.db2": redis.db2?.split(",")?.[0]?.substring(5), "redis.db10": redis.db10?.split(",")?.[0]?.substring(5), "pg.connection": query?.length, dbsize: dbSize, filesize: 0, }, metricSort, system: { os: osInfo, release: os.release(), core: cpuInfo?.length, cpu: cpuInfo?.[0]?.model, ram: formatMemoryUsage(totalMemory), db: dbVerion, redis: rclient?.server_info?.redis_version, node: process.version, }, top: topProcess, query, }; }