Improve metrics

This commit is contained in:
2023-11-15 11:14:16 +01:00
parent 652be94621
commit 74a4204046
4 changed files with 48 additions and 33 deletions

View File

@@ -6,6 +6,7 @@ const { createBaseLogger, createSessionLogger } = require("./logger");
const { verifyDefaults, verifyExists } = require("./utils"); const { verifyDefaults, verifyExists } = require("./utils");
const { centerOptions } = require("./cliOptions"); const { centerOptions } = require("./cliOptions");
const crypto = require("crypto"); const crypto = require("crypto");
const { MetricManager } = require("./metrics/metricManager");
const logger = createBaseLogger(); const logger = createBaseLogger();
const options = commandLineArgs(centerOptions); const options = commandLineArgs(centerOptions);
@@ -27,6 +28,8 @@ if (options.help) {
process.exit(0); process.exit(0);
} }
const metricManager = new MetricManager();
verifyDefaults(options, centerOptions); verifyDefaults(options, centerOptions);
verifyExists(options.port, "Port can not be undefined or empty! (--port)", logger); verifyExists(options.port, "Port can not be undefined or empty! (--port)", logger);
verifyExists(options.systemid, "SystemID can not be undefined or empty! (--systemid)", logger); verifyExists(options.systemid, "SystemID can not be undefined or empty! (--systemid)", logger);
@@ -41,7 +44,7 @@ const sendTimer = new NanoTimer();
// TODO: Fix issue where a client disconnecting does not stop this timer // TODO: Fix issue where a client disconnecting does not stop this timer
// TODO: Fix issue where only one session is being utilized because they all share the same timer // TODO: Fix issue where only one session is being utilized because they all share the same timer
// Instead just use the same timer but make a pool of connections; That way both problems will be solved // Instead just use the same timer but make a pool of connections; That way both problems will be solved
function startInterval(session, sessionLogger) { function startInterval(session, sessionLogger, rxMetrics) {
if (!options.messagecount > 0) { if (!options.messagecount > 0) {
sessionLogger.info("No messages to send"); sessionLogger.info("No messages to send");
return; return;
@@ -49,10 +52,10 @@ function startInterval(session, sessionLogger) {
sendTimer.setInterval( sendTimer.setInterval(
async () => { async () => {
if (sent >= options.messagecount) { if (sent >= options.messagecount) {
sessionLogger.info(`Finished sending messages success:${success}, failed:${failed}, idling...`); // sessionLogger.info(`Finished sending messages success:${success}, failed:${failed}, idling...`);
sendTimer.clearInterval(); sendTimer.clearInterval();
} else if (inFlight < options.window) { } else if (inFlight < options.window) {
sessionLogger.info(`Sending message ${sent + 1}/${options.messagecount}`); // sessionLogger.info(`Sending message ${sent + 1}/${options.messagecount}`);
session.deliver_sm( session.deliver_sm(
{ {
source_addr: options.source, source_addr: options.source,
@@ -62,7 +65,7 @@ function startInterval(session, sessionLogger) {
function (pdu) { function (pdu) {
inFlight--; inFlight--;
if (pdu.command_status === 0) { if (pdu.command_status === 0) {
sessionLogger.info(`Received response with id ${pdu.message_id}`); // sessionLogger.info(`Received response with id ${pdu.message_id}`);
success++; success++;
} else { } else {
sessionLogger.warn(`Message failed with id ${pdu.message_id}`); sessionLogger.warn(`Message failed with id ${pdu.message_id}`);
@@ -70,6 +73,7 @@ function startInterval(session, sessionLogger) {
} }
} }
); );
rxMetrics.AddEvent();
sent++; sent++;
inFlight++; inFlight++;
} else { } else {
@@ -93,7 +97,10 @@ const server = smpp.createServer(
debug: options.debug, debug: options.debug,
}, },
function (session) { function (session) {
const sessionLogger = createSessionLogger(sessionid++); const id = sessionid++;
const sessionLogger = createSessionLogger(id);
const rxMetrics = metricManager.AddMetrics(`Session-${id}-RX`);
const txMetrics = metricManager.AddMetrics(`Session-${id}-TX`);
session.on("bind_transceiver", function (pdu) { session.on("bind_transceiver", function (pdu) {
if (pdu.system_id === options.systemid && pdu.password === options.password) { if (pdu.system_id === options.systemid && pdu.password === options.password) {
@@ -115,7 +122,8 @@ const server = smpp.createServer(
}); });
session.on("submit_sm", async function (pdu) { session.on("submit_sm", async function (pdu) {
if (!options.dr) { if (!options.dr) {
sessionLogger.info("Replying to incoming submit_sm"); // sessionLogger.info("Replying to incoming submit_sm");
rxMetrics.AddEvent();
session.send(pdu.response()); session.send(pdu.response());
return; return;
} }
@@ -157,6 +165,7 @@ const server = smpp.createServer(
}; };
sessionLogger.info(`Generated DR as ${drMessage}`); sessionLogger.info(`Generated DR as ${drMessage}`);
session.deliver_sm(DRPdu); session.deliver_sm(DRPdu);
txMetrics.AddEvent();
}); });
session.on("close", function () { session.on("close", function () {

View File

@@ -39,14 +39,22 @@ let success = 0;
let failed = 0; let failed = 0;
const sendTimer = new NanoTimer(); const sendTimer = new NanoTimer();
function startInterval(session, sessionLogger) { function startInterval(session, sessionLogger, metrics) {
if (!metrics.progress) {
metrics.progress = metricManager.AddMetrics("Send progress", false);
metrics.progress.bar.total = options.messagecount;
metrics.window = metricManager.AddMetrics("Send window", false);
metrics.window.bar.total = options.window;
}
sendTimer.setInterval( sendTimer.setInterval(
async () => { async () => {
if (sent >= options.messagecount) { if (sent >= options.messagecount) {
sessionLogger.info(`Finished sending messages success:${success}, failed:${failed}, idling...`); // sessionLogger.info(`Finished sending messages success:${success}, failed:${failed}, idling...`);
sendTimer.clearInterval(); sendTimer.clearInterval();
} else if (inFlight < options.window) { } else if (inFlight < options.window) {
sessionLogger.info(`Sending message ${sent + 1}/${options.messagecount}`); // sessionLogger.info(`Sending message ${sent + 1}/${options.messagecount}`);
metrics.progress.bar.increment();
metrics.window.bar.increment();
session.submit_sm( session.submit_sm(
{ {
source_addr: options.source, source_addr: options.source,
@@ -54,9 +62,10 @@ function startInterval(session, sessionLogger) {
short_message: options.message, short_message: options.message,
}, },
function (pdu) { function (pdu) {
metrics.window.bar.update(metrics.window.bar.value - 1);
inFlight--; inFlight--;
if (pdu.command_status === 0) { if (pdu.command_status === 0) {
sessionLogger.info(`Received response with id ${pdu.message_id}`); // sessionLogger.info(`Received response with id ${pdu.message_id}`);
success++; success++;
} else { } else {
sessionLogger.warn(`Message failed with id ${pdu.message_id}`); sessionLogger.warn(`Message failed with id ${pdu.message_id}`);
@@ -64,14 +73,15 @@ function startInterval(session, sessionLogger) {
} }
} }
); );
metrics.txMetrics.AddEvent();
sent++; sent++;
inFlight++; inFlight++;
} else { } else {
sessionLogger.warn( // sessionLogger.warn(
`${inFlight}/${options.window} messages pending, waiting for a reply before sending more` // `${inFlight}/${options.window} messages pending, waiting for a reply before sending more`
); // );
sendTimer.clearInterval(); sendTimer.clearInterval();
setTimeout(() => startInterval(session, sessionLogger), options.windowsleep); setTimeout(() => startInterval(session, sessionLogger, metrics), options.windowsleep);
} }
}, },
"", "",
@@ -80,15 +90,6 @@ function startInterval(session, sessionLogger) {
} }
const metricManager = new MetricManager(); const metricManager = new MetricManager();
// async function main() {
// const test1 = metricManager.AddMetrics("test");
// for (let i = 0; i < 1e5; i++) {
// test1.AddEvent();
// test1.UpdateBar();
// await setTimeout(() => {}, 200);
// }
// }
// main();
for (let i = 0; i < options.sessions; i++) { for (let i = 0; i < options.sessions; i++) {
const sessionLogger = createSessionLogger(i); const sessionLogger = createSessionLogger(i);
@@ -115,7 +116,10 @@ for (let i = 0; i < options.sessions; i++) {
); );
const rxMetrics = metricManager.AddMetrics(`Session-${i}-RX`); const rxMetrics = metricManager.AddMetrics(`Session-${i}-RX`);
const txMetrics = metricManager.AddMetrics(`Session-${i}-TX`); const txMetrics = metricManager.AddMetrics(`Session-${i}-TX`);
startInterval(session, sessionLogger); startInterval(session, sessionLogger, {
rxMetrics,
txMetrics,
});
// TODO: Add error message for invalid systemid and password // TODO: Add error message for invalid systemid and password
session.on("deliver_sm", function (pdu) { session.on("deliver_sm", function (pdu) {

View File

@@ -13,10 +13,11 @@ class MetricManager {
}, },
cliProgress.Presets.shades_grey cliProgress.Presets.shades_grey
); );
setInterval(() => this.multibar.update(), 100);
} }
AddMetrics(name) { AddMetrics(name, refresh = true) {
const metric = new Metric(name, this.multibar, this.metricBufferSize); const metric = new Metric(name, this.multibar, this.metricBufferSize, refresh);
return metric; return metric;
} }
} }

View File

@@ -1,14 +1,16 @@
const { CircularBuffer } = require("./circularBuffer"); const { CircularBuffer } = require("./circularBuffer");
class Metric { class Metric {
constructor(barName, multibar, bufferSize) { constructor(barName, multibar, bufferSize, refresh = true) {
this.multibar = multibar; this.multibar = multibar;
this.pbar = multibar.create(0, 0); this.bar = multibar.create(0, 0);
this.pbar.update(0, { name: barName }); this.bar.update(0, { name: barName });
this.buffer = new CircularBuffer(bufferSize); this.buffer = new CircularBuffer(bufferSize);
this.maxRate = 0; this.maxRate = 0;
if (refresh) {
setInterval(this.UpdateBar.bind(this), 100); setInterval(this.UpdateBar.bind(this), 100);
} }
}
AddEvent() { AddEvent() {
const timestamp = Date.now(); const timestamp = Date.now();
@@ -28,11 +30,10 @@ class Metric {
UpdateBar() { UpdateBar() {
const eps = this.GetRate(); const eps = this.GetRate();
if (eps > this.maxRate) { if (eps > this.maxRate) {
this.pbar.total = eps; this.bar.total = eps;
this.maxRate = eps; this.maxRate = eps;
} }
this.pbar.update(eps); this.bar.update(eps);
this.multibar.update();
} }
} }