@opengis/fastify-table
Version:
core-plugins
132 lines (107 loc) • 4.82 kB
JavaScript
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`;
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 = await pg.query('select version();').then(el => el.rows?.[0]?.version);
const dbSize = dbsize
|| (await pg.query(`select pg_size_pretty(pg_database_size('${dbName}'));`).then(el => el.rows?.[0]?.pg_size_pretty));
const { rows: query = [] } = await pg.query(sqlQuery, [dbName]);
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 totalCpu = (Object.values(cpuInfo[0].times).reduce((acc, tv) => acc + tv, 0)) * cpuInfo.length;
const totalMemory = os.totalmem();
const memory = process.memoryUsage();
const resource = process.resourceUsage();
const currentCpuUsage = (((process.cpuUsage().user + process.cpuUsage().system) * 1000) / totalCpu) * 100;
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 = await pg.query('select extract(\'epoch\' from current_timestamp - pg_postmaster_start_time())::int as uptime')
.then(el => el.rows?.[0]?.uptime);
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', `${dbName}:user:*`, 'count', '10000']) : [];
// const userOnline = await rclient10.scan(['0', 'match', 'sess:*', 'count', '10000']);
return {
process: {
root: process.cwd(),
processFolder,
saveDirectory: filesFolder,
dbhost: pg?.options?.host,
dbport: pg?.options?.port,
dbname: dbName,
},
uptime: {
node: Math.round(process.uptime()),
system: os.uptime(),
pg: uptime,
redis: redis.uptime_in_seconds - 0,
},
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,
};
}