|
|
@@ -3,15 +3,20 @@ import fsp from 'fs/promises';
|
|
|
import moment from 'moment';
|
|
|
import { exec } from 'node-utils/shell';
|
|
|
import path from 'path';
|
|
|
+import { format } from 'util';
|
|
|
|
|
|
import { HttpStatusException } from '../../common/lib/http-status.exception';
|
|
|
import { Logger } from '../../common/util/logger.class';
|
|
|
|
|
|
+import { MemoryUsage, TopTTY } from './top-tty';
|
|
|
+
|
|
|
const DATA_DIR = process.env.DATA_DIR || 'data';
|
|
|
const DATA_BUFFER_FILE = path.resolve(DATA_DIR, 'buffer.csv');
|
|
|
const DATA_BUFFER_REMAINS = path.resolve(DATA_DIR, 'remains.csv');
|
|
|
const DATA_REDUCED_FILE = path.resolve(DATA_DIR, 'reduced.csv');
|
|
|
const TIMESTAMP_FORMAT = `YYYY-MM-DD[T]HH:mm:ss.SSSZZ`;
|
|
|
+const WRITE_BUFFER_INTERVAL = 500; // [ms]
|
|
|
+const READ_HDD_INTERVAL = 300; // [s]
|
|
|
const REDUCE_INTERVAL_MINUTES = 5;
|
|
|
const REDUCE_GROUP_MINUTES = 1;
|
|
|
|
|
|
@@ -42,6 +47,13 @@ const CSV_COLS = {
|
|
|
export class Collector {
|
|
|
private intervalHdl?: NodeJS.Timer;
|
|
|
|
|
|
+ private currentRamUsage: MemoryUsage = { unit: 'B', avail: 0, used: 0 };
|
|
|
+ private currentCpuUsage: number = 0;
|
|
|
+ private currentHddUsage: { time: number; mounts: Array<{ mount: string; stats: string }> } = {
|
|
|
+ time: 0,
|
|
|
+ mounts: []
|
|
|
+ };
|
|
|
+
|
|
|
constructor() {
|
|
|
(async () => {
|
|
|
try {
|
|
|
@@ -60,26 +72,44 @@ export class Collector {
|
|
|
}
|
|
|
|
|
|
public startLoop() {
|
|
|
- this.intervalHdl = setInterval(this.loop.bind(this), 500);
|
|
|
+ this.intervalHdl = setInterval(this.loop.bind(this), WRITE_BUFFER_INTERVAL);
|
|
|
+
|
|
|
+ const tty = new TopTTY();
|
|
|
+ tty.subscribe.cpu(usage => (this.currentCpuUsage = usage));
|
|
|
+ tty.subscribe.ram(usage => (this.currentRamUsage = usage));
|
|
|
+ tty.runloop();
|
|
|
}
|
|
|
|
|
|
private async loop() {
|
|
|
try {
|
|
|
const now = moment();
|
|
|
const time = now.format(TIMESTAMP_FORMAT);
|
|
|
- const cpu = (await exec(`./cpu.sh`)).trim();
|
|
|
- const ram = (await exec(`./ram.sh`)).trim();
|
|
|
|
|
|
- const hdd: string[] = [];
|
|
|
- for (const mount of MONITOR_MOUNTS) {
|
|
|
- try {
|
|
|
- const stats = (await exec(`./hdd.sh "${mount}"`)).trim();
|
|
|
- if (stats?.length) hdd.push(`${mount} ${stats}`);
|
|
|
- } catch (err) {
|
|
|
- Logger.warn('[WARN] Error while getting space usage of mount', mount, ':', err);
|
|
|
+ if (now.unix() - this.currentHddUsage.time > READ_HDD_INTERVAL) {
|
|
|
+ this.currentHddUsage.time = now.unix();
|
|
|
+ this.currentHddUsage.mounts = [];
|
|
|
+
|
|
|
+ for (const mount of MONITOR_MOUNTS) {
|
|
|
+ try {
|
|
|
+ const stats = (await exec(`./hdd.sh "${mount}"`)).trim();
|
|
|
+ if (stats?.length) this.currentHddUsage.mounts.push({ mount, stats });
|
|
|
+ } catch (err) {
|
|
|
+ Logger.warn('[WARN] Error while getting space usage of mount', mount, ':', err);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const hdd: string[] = this.currentHddUsage.mounts.map(({ mount, stats }) => `${mount} ${stats}`);
|
|
|
+
|
|
|
+ if (!this.currentRamUsage.avail) return;
|
|
|
+
|
|
|
+ const ram = format(
|
|
|
+ '%s/%s %s',
|
|
|
+ (Math.round(this.currentRamUsage.used * 100) / 100).toFixed(2),
|
|
|
+ (Math.round(this.currentRamUsage.avail * 100) / 100).toFixed(2),
|
|
|
+ this.currentRamUsage.unit
|
|
|
+ );
|
|
|
+ const cpu = (Math.round(this.currentCpuUsage * 100) / 100).toFixed(2);
|
|
|
const data = `${time};${cpu};${ram}${hdd.length ? `;${hdd.join(';')}` : ''}\n`;
|
|
|
|
|
|
// Time to reduce buffer?
|