1
0
mirror of https://github.com/laurent22/joplin.git synced 2026-04-18 19:42:23 +02:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Laurent Cozic 17a7fcff2d fixed tests 2026-04-17 08:40:24 +01:00
Laurent Cozic a937934bb1 update 2026-04-17 07:32:49 +01:00
4 changed files with 24 additions and 59 deletions
-2
View File
@@ -45,7 +45,6 @@
"markdown-it": "13.0.2",
"mustache": "4.2.0",
"node-cron": "3.0.3",
"node-os-utils": "1.3.7",
"nodemailer": "6.10.1",
"nodemon": "3.1.11",
"otplib": "12.0.1",
@@ -76,7 +75,6 @@
"@types/markdown-it": "13.0.9",
"@types/mustache": "4.2.6",
"@types/node": "18.19.130",
"@types/node-os-utils": "1.3.4",
"@types/nodemailer": "6.4.21",
"@types/yargs": "17.0.35",
"@types/zxcvbn": "4.4.5",
+12 -12
View File
@@ -6,13 +6,10 @@ describe('metrics', () => {
beforeEach(() => {
clearMetrics();
jest.useFakeTimers({
// Timers need to auto-advance to support node-os-utils.
advanceTimers: true,
});
jest.useFakeTimers();
});
it('should generate a heartbeat message', async () => {
it('should generate a heartbeat message', () => {
const requestId1 = Math.random().toString();
const requestId2 = Math.random().toString();
const requestId3 = Math.random().toString();
@@ -22,18 +19,19 @@ describe('metrics', () => {
onRequestStart(requestId3);
onRequestComplete(requestId2);
jest.advanceTimersByTime(Second);
const regex = /Cpu: (.*?)%; Mem: (.*?) \/ (.*?) MB \((.*?)%\); Req: 3 \/ min; Active req: 2/;
const message = await heartbeatMessage();
const message = heartbeatMessage();
const match = message.match(regex);
expect(match.length).toBe(5);
expect(Number(match[1])).toBeGreaterThan(0);
expect(Number(match[2])).toBeLessThan(Number(match[3]));
expect(Number(match[3])).toBeGreaterThan(0);
});
it('should count the number of requests per minute', async () => {
it('should count the number of requests per minute', () => {
const mockRequest = () => {
const id = uuid.create();
onRequestStart(id);
@@ -44,18 +42,20 @@ describe('metrics', () => {
mockRequest();
jest.advanceTimersByTime(Second);
}
expect(await heartbeatMessage()).toMatch(/Req: 10 \/ min/);
expect(heartbeatMessage()).toMatch(/Req: 10 \/ min/);
jest.advanceTimersByTime(Minute * 15);
expect(await heartbeatMessage()).toMatch(/Req: 0 \/ min/);
expect(heartbeatMessage()).toMatch(/Req: 0 \/ min/);
mockRequest();
expect(await heartbeatMessage()).toMatch(/Req: 1 \/ min/);
jest.advanceTimersByTime(Second);
expect(heartbeatMessage()).toMatch(/Req: 1 \/ min/);
jest.advanceTimersByTime(Minute * 2);
mockRequest();
jest.advanceTimersByTime(Second * 10);
mockRequest();
expect(await heartbeatMessage()).toMatch(/Req: 2 \/ min/);
jest.advanceTimersByTime(Second);
expect(heartbeatMessage()).toMatch(/Req: 2 \/ min/);
});
});
+12 -29
View File
@@ -3,7 +3,7 @@
// Provides metrics about the operating system and server application, and format them in a message
// that can be printed to log.
import { MemUsedInfo, cpu, mem } from 'node-os-utils';
import * as os from 'os';
import { Minute } from './time';
import Logger from '@joplin/utils/Logger';
@@ -53,43 +53,26 @@ export const clearMetrics = () => {
activeRequests_.clear();
};
export const heartbeatMessage = async () => {
const interval = 1000;
const promises: Promise<void>[] = [];
interface Info {
cpu?: number;
memory?: MemUsedInfo;
}
const info: Info = {};
const getCpu = async () => {
info.cpu = await cpu.usage(interval);
};
const getMemory = async () => {
info.memory = await mem.used();
};
promises.push(getCpu());
promises.push(getMemory());
await Promise.all(promises);
export const heartbeatMessage = () => {
const loadAvg = os.loadavg();
const totalMemMb = Math.round(os.totalmem() / (1024 * 1024));
const freeMemMb = Math.round(os.freemem() / (1024 * 1024));
const usedMemMb = totalMemMb - freeMemMb;
const line: string[] = [];
line.push(`Cpu: ${info.cpu}%`);
line.push(`Mem: ${info.memory.usedMemMb} / ${info.memory.totalMemMb} MB (${Math.round((info.memory.usedMemMb / info.memory.totalMemMb) * 100)}%)`);
const cpuCount = os.cpus().length;
const cpuPercent = Math.round((loadAvg[0] / cpuCount) * 100);
line.push(`Cpu: ${cpuPercent}%`);
line.push(`Mem: ${usedMemMb} / ${totalMemMb} MB (${Math.round((usedMemMb / totalMemMb) * 100)}%)`);
line.push(`Req: ${requestsPerMinute()} / min`);
line.push(`Active req: ${activeRequests_.size}`);
return line.join('; ');
};
export const logHeartbeat = async () => {
logger.info(await heartbeatMessage());
export const logHeartbeat = () => {
logger.info(heartbeatMessage());
};
export const onRequestStart = (requestId: string) => {
-16
View File
@@ -13305,7 +13305,6 @@ __metadata:
"@types/markdown-it": "npm:13.0.9"
"@types/mustache": "npm:4.2.6"
"@types/node": "npm:18.19.130"
"@types/node-os-utils": "npm:1.3.4"
"@types/nodemailer": "npm:6.4.21"
"@types/qrcode": "npm:1.5.6"
"@types/uuid": "npm:11.0.0"
@@ -13330,7 +13329,6 @@ __metadata:
mustache: "npm:4.2.0"
node-cron: "npm:3.0.3"
node-mocks-http: "npm:1.17.2"
node-os-utils: "npm:1.3.7"
nodemailer: "npm:6.10.1"
nodemon: "npm:3.1.11"
otplib: "npm:12.0.1"
@@ -19431,13 +19429,6 @@ __metadata:
languageName: node
linkType: hard
"@types/node-os-utils@npm:1.3.4":
version: 1.3.4
resolution: "@types/node-os-utils@npm:1.3.4"
checksum: 10/e0adbb62b9503b86a16c5a09058104ec81975ad58c6c28594986de0602378f4c87d0b46d1f5445a778607e42df1b318cdea91e2ac54994572904490dc1a086af
languageName: node
linkType: hard
"@types/node-rsa@npm:1.1.4":
version: 1.1.4
resolution: "@types/node-rsa@npm:1.1.4"
@@ -44292,13 +44283,6 @@ __metadata:
languageName: node
linkType: hard
"node-os-utils@npm:1.3.7":
version: 1.3.7
resolution: "node-os-utils@npm:1.3.7"
checksum: 10/728aa20051f6502158ed5c58de4c4073a5715285151dc99a311bf9968a163019ca0b96d4432c244758d5545c896137f1e0be00a54f7d6f88cac4ac0dc07c2ad2
languageName: node
linkType: hard
"node-persist@npm:3.1.3":
version: 3.1.3
resolution: "node-persist@npm:3.1.3"