Skip to content

Commit

Permalink
Merge pull request #109 from monti-apm/feat/sc-839/record-system-memo…
Browse files Browse the repository at this point in the history
…ry-metrics

[sc-839] feat: record system memory metrics
  • Loading branch information
zodern authored Feb 21, 2024
2 parents d93f639 + 802b8d9 commit 8d76896
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 21 deletions.
14 changes: 9 additions & 5 deletions lib/models/system.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { getMongoDriverStats, resetMongoDriverStats } from '../hijack/mongo_driv
import { KadiraModel } from './0model';
import { EventLoopMonitor } from '../event_loop_monitor.js';
import { Ntp } from '../ntp';
import os from 'os';

export const MEMORY_ROUNDING_FACTOR = 100 * 1024; // 100kb
const EVENT_LOOP_ROUNDING_FACTOR = 500; // microseconds

function roundUsingFactor (number, factor) {
Expand Down Expand Up @@ -53,11 +55,13 @@ SystemModel.prototype.buildPayload = function () {
metrics.sessions = countKeys(Meteor.server.sessions);

let memoryUsage = process.memoryUsage();
metrics.memory = memoryUsage.rss / (1024 * 1024);
metrics.memoryArrayBuffers = (memoryUsage.arrayBuffers || 0) / (1024 * 1024);
metrics.memoryExternal = memoryUsage.external / (1024 * 1024);
metrics.memoryHeapUsed = memoryUsage.heapUsed / (1024 * 1024);
metrics.memoryHeapTotal = memoryUsage.heapTotal / (1024 * 1024);
metrics.memory = roundUsingFactor(memoryUsage.rss, MEMORY_ROUNDING_FACTOR) / (1024 * 1024);
metrics.memoryArrayBuffers = roundUsingFactor(memoryUsage.arrayBuffers || 0, MEMORY_ROUNDING_FACTOR) / (1024 * 1024);
metrics.memoryExternal = roundUsingFactor(memoryUsage.external, MEMORY_ROUNDING_FACTOR) / (1024 * 1024);
metrics.memoryHeapUsed = roundUsingFactor(memoryUsage.heapUsed, MEMORY_ROUNDING_FACTOR) / (1024 * 1024);
metrics.memoryHeapTotal = roundUsingFactor(memoryUsage.heapTotal, MEMORY_ROUNDING_FACTOR) / (1024 * 1024);
metrics.freeMemory = roundUsingFactor(os.freemem(), MEMORY_ROUNDING_FACTOR) / (1024 * 1024);
metrics.totalMemory = roundUsingFactor(os.totalmem(), MEMORY_ROUNDING_FACTOR) / (1024 * 1024);

metrics.newSessions = this.newSessions;
this.newSessions = 0;
Expand Down
18 changes: 17 additions & 1 deletion tests/_helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,20 @@ export const GetPubSubPayload = function (detailInfoNeeded) {
return Kadira.models.pubsub.buildPayload(detailInfoNeeded).pubMetrics;
};

export function findMetricsForMethod (name) {
let metrics = Object.values(Kadira.models.methods.methodMetricsByMinute);

let candidates = [];

metrics.forEach(metric => {
if (metric.methods[name]) {
candidates.push(metric.methods[name]);
}
});

return candidates[candidates.length - 1];
}

export const Wait = function (time) {
let f = new Future();
Meteor.setTimeout(function () {
Expand Down Expand Up @@ -188,7 +202,9 @@ export const WithDocCacheGetSize = function (fn, patchedSize) {
}
};

export const releaseParts = Meteor.release.split('METEOR@')[1].split('.').map(num => parseInt(num, 10));
// Meteor.release is none when running from checkout
let release = Meteor.release === 'none' ? 'METEOR@2.5.0' : Meteor.release;
export const releaseParts = release.split('METEOR@')[1].split('.').map(num => parseInt(num, 10));

export const withRoundedTime = (fn) => (test) => {
const date = new Date();
Expand Down
4 changes: 2 additions & 2 deletions tests/event_loop_monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ Tinytest.addAsync(
Meteor.setTimeout(function () {
let status = monitor.status();

test.isTrue(status.pctBlock > 0);
test.isTrue(status.pctBlock > 0, `${status.pctBlock} > 0; ${JSON.stringify(status)}`);
monitor.stop();

status = monitor.status();

test.isTrue(status.pctBlock === 0);
test.isTrue(status.pctBlock === 0, `${status.pctBlock} === 0`);
done();
}, 200);
}
Expand Down
8 changes: 7 additions & 1 deletion tests/hijack/subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
EnableTrackingMethods, FindMetricsForPub,
GetMeteorClient, GetPubSubMetrics, GetPubSubPayload, RegisterPublication,
SubscribeAndWait,
TestHelpers, Wait
TestHelpers, Wait, waitForConnection
} from '../_helpers/helpers';

Tinytest.add(
Expand Down Expand Up @@ -146,9 +146,13 @@ Tinytest.add(

let client = TestHelpers.getMeteorClient();

waitForConnection(client);

let start = Date.now();
let st = Date.now();
let h1 = TestHelpers.subscribeAndWait(client, 'tinytest-data');
let elapsedTime = Date.now() - st;
console.log('elapsed 1', elapsedTime);

TestHelpers.wait(100);

Expand All @@ -157,6 +161,8 @@ Tinytest.add(
st = Date.now();
h1.stop();
elapsedTime += Date.now() - st;
console.log('elapsed 2', Date.now() - st);
console.log('elapsed total', Date.now() - start);

TestHelpers.wait(100);

Expand Down
9 changes: 4 additions & 5 deletions tests/models/methods.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { EJSON } from 'meteor/ejson';
import { MethodsModel } from '../../lib/models/methods';
import { TestData } from '../_helpers/globals';
import { CleanTestData, GetMeteorClient, RegisterMethod, Wait, WithDocCacheGetSize } from '../_helpers/helpers';
import { CleanTestData, GetMeteorClient, RegisterMethod, Wait, WithDocCacheGetSize, findMetricsForMethod } from '../_helpers/helpers';
import { Meteor } from 'meteor/meteor';
import { Ntp } from '../../lib/ntp';

Tinytest.add(
'Models - Method - buildPayload simple',
Expand Down Expand Up @@ -204,7 +203,7 @@ Tinytest.addAsync('Models - Method - Waited On - track wait time of queued messa

Meteor._sleepForMs(1000);

const metrics = Kadira.models.methods._getMetrics(Ntp._now(), methodId);
const metrics = findMetricsForMethod(methodId);

test.isTrue(metrics.waitedOn > 25, `${metrics.waitedOn} should be greater than 25`);
test.isTrue(metrics.waitedOn <= 6000, `${metrics.waitedOn} should be less than 6k`);
Expand All @@ -227,7 +226,7 @@ Tinytest.addAsync('Models - Method - Waited On - check unblock time', async (tes

Meteor._sleepForMs(1000);

const metrics = Kadira.models.methods._getMetrics(Ntp._now(), methodId);
const metrics = findMetricsForMethod(methodId);

test.isTrue(metrics.waitedOn <= 1, 'waitedOn should be less or equal than 1');

Expand All @@ -247,7 +246,7 @@ Tinytest.addAsync('Models - Method - Waited On - track wait time of next message

Meteor._sleepForMs(200);

const metrics = Kadira.models.methods._getMetrics(Ntp._now(), slowMethod);
const metrics = findMetricsForMethod(slowMethod);
test.isTrue(metrics.waitedOn >= 20, `${metrics.waitedOn} should be greater than 20`);

done();
Expand Down
15 changes: 10 additions & 5 deletions tests/models/pubsub.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
addTestWithRoundedTime,
CleanTestData,
CloseClient,
FindMetricsForPub,
GetMeteorClient,
GetPubSubPayload,
RegisterMethod,
Expand All @@ -14,7 +15,6 @@ import {
} from '../_helpers/helpers';
import { TestData } from '../_helpers/globals';
import { Meteor } from 'meteor/meteor';
import { Ntp } from '../../lib/ntp';

addTestWithRoundedTime(
'Models - PubSub - Metrics - same date',
Expand Down Expand Up @@ -746,7 +746,7 @@ Tinytest.addAsync('Models - PubSub - Wait Time - track wait time', async (test,

Meteor._sleepForMs(100);

const metrics = Kadira.models.pubsub._getMetrics(Ntp._now(), pubName);
const metrics = FindMetricsForPub(pubName);

test.isTrue(metrics.waitTime > 0, `${metrics.waitTime} should be greater than 0`);

Expand All @@ -769,7 +769,7 @@ Tinytest.addAsync('Models - PubSub - Waited On - track wait time of queued messa

Meteor._sleepForMs(1000);

const metrics = Kadira.models.pubsub._getMetrics(Ntp._now(), pubName);
const metrics = FindMetricsForPub(pubName);

test.isTrue(metrics.waitedOn > 1000, `${metrics.waitedOn} should be greater than 1000`);

Expand All @@ -791,7 +791,12 @@ Tinytest.addAsync('Models - PubSub - Waited On - track waited on time of next me
client.subscribe('tinytest-waited-on');
client.call(fastMethod);

const metrics = Kadira.models.pubsub._getMetrics(Ntp._now(), 'tinytest-waited-on');
const metrics = FindMetricsForPub('tinytest-waited-on');

if (metrics.waitedOn === 0) {
console.dir(metrics);
}

test.isTrue(metrics.waitedOn > 10, `${metrics.waitedOn} should be greater than 10`);

done();
Expand All @@ -812,7 +817,7 @@ Tinytest.addAsync('Models - PubSub - Waited On - track wait when unblock', async
client.subscribe('tinytest-waited-on2');
client.call(fastMethod);

const metrics = Kadira.models.pubsub._getMetrics(Ntp._now(), 'tinytest-waited-on2');
const metrics = FindMetricsForPub('tinytest-waited-on2');

test.isTrue(metrics.waitedOn > 8, `${metrics.waitedOn} should be greater than 8`);

Expand Down
4 changes: 2 additions & 2 deletions tests/models/system.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { SystemModel } from '../../lib/models/system';
import { MEMORY_ROUNDING_FACTOR, SystemModel } from '../../lib/models/system';
import { Wait } from '../_helpers/helpers';

/**
Expand All @@ -13,8 +13,8 @@ Tinytest.add(
setTimeout(callback, 500);
})();
let payload = model.buildPayload().systemMetrics[0];

test.isTrue(payload.memory > 0, `memory: ${payload.memory}`);
test.isTrue((payload.memory * 1024 * 1024 /* in bytes */) % MEMORY_ROUNDING_FACTOR === 0, 'memory is rounded');
test.isTrue(payload.pcpu >= 0, `pcpu: ${payload.pcpu}`);
test.isTrue(payload.sessions >= 0, `sessions: ${payload.sessions}`);
test.isTrue(payload.endTime >= payload.startTime + 500, `time: ${payload.endTime} - ${payload.startTime}`);
Expand Down

0 comments on commit 8d76896

Please sign in to comment.