Added database monitoring metric
ADD
src/monitoring/DatabaseMonitoringMetric.ts
+import client, { Gauge, LabelValues } from 'prom-client';
+
+class DatabaseMonitoringMetric {
+ private gaugeMetricAvg: client.Gauge;
+ private gaugeMetricCount: client.Gauge;
+ private gaugeMetricSum: client.Gauge;
+ private metricCount = 0;
+ private metricSum = 0;
+ private metricAvg = 0;
+
+ // Normal signature with defaults
+ public constructor(metricname: string, suffix: number, metrichelp: string, labelNames: string[]) {
+ this.gaugeMetricAvg = new client.Gauge({
+ name: 'mongod_' + metricname + '_avg_' + suffix,
+ help: metrichelp,
+ labelNames: labelNames,
+ });
+ this.gaugeMetricCount = new client.Gauge({
+ name: 'mongod_' + metricname + '_count_' + suffix,
+ help: metrichelp,
+ labelNames: labelNames,
+ });
+ this.gaugeMetricSum = new client.Gauge({
+ name: 'mongod_' + metricname + '_sum_' + suffix,
+ help: metrichelp,
+ labelNames: labelNames,
+ });
+ }
+
+ public register(registry: client.Registry): void {
+ registry.registerMetric(this.gaugeMetricAvg);
+ registry.registerMetric(this.gaugeMetricCount);
+ registry.registerMetric(this.gaugeMetricSum);
+ }
+
+ public setValue(labels: LabelValues<string>, value: number) {
+ if (this.metricCount === 0) {
+ this.metricAvg = 0;
+ }
+ this.metricSum += value;
+ this.metricAvg = (this.metricAvg * this.metricCount + value) / (this.metricCount + 1);
+ this.metricCount++;
+ this.gaugeMetricCount.labels(labels).set(this.metricCount);
+ this.gaugeMetricSum.labels(labels).set(this.metricSum);
+ this.gaugeMetricAvg.labels(labels).set(this.metricAvg);
+ }
+
+ public clear() {
+ this.metricSum = 0;
+ this.metricAvg = 0;
+ this.metricCount = 0;
+ }
+}
+export { DatabaseMonitoringMetric };

MODIFY
src/monitoring/MonitoringServer.ts
src/monitoring/MonitoringServer.ts
import client from 'prom-client';
+import { DatabaseMonitoringMetric } from './DatabaseMonitoringMetric';
export default abstract class MonitoringServer {
public abstract start(): void;
+
public abstract getGauge(name: string): client.Gauge | undefined;
- public abstract createGaugeMetric(metricname : string, metrichelp : string, labelNames? : string[]) : client.Gauge;
-}
+ public abstract createGaugeMetric(
+ metricname: string,
+ metrichelp: string,
+ labelNames?: string[]
+ ): client.Gauge;
+
+ public abstract getDatabaseMetric(
+ metricname: string,
+ suffix: number,
+ metrichelp: string,
+ labelNames: string[]
+ ): DatabaseMonitoringMetric;
+}

MODIFY
src/monitoring/prometheus/PrometheusMonitoringServer.ts
src/monitoring/prometheus/PrometheusMonitoringServer.ts
@@ -6,6 +6,7 @@ import Constants from '../../utils/Constants';
import ExpressUtils from '../../server/ExpressUtils';
import Logging from '../../utils/Logging';
import MonitoringConfiguration from '../../types/configuration/MonitoringConfiguration';
+import { DatabaseMonitoringMetric } from '../DatabaseMonitoringMetric';
import MonitoringServer from '../MonitoringServer';
import { ServerUtils } from '../../server/ServerUtils';
import global from '../../types/GlobalType';
@@ -16,6 +17,7 @@ export default class PrometheusMonitoringServer extends MonitoringServer {
private monitoringConfig: MonitoringConfiguration;
private expressApplication: Application;
private mapGauge = new Map<string, Gauge>();
+ private mapDatabaseMetric = new Map<string, DatabaseMonitoringMetric>();
private clientRegistry = new client.Registry();
public constructor(monitoringConfig: MonitoringConfiguration) {
@@ -46,6 +48,9 @@ export default class PrometheusMonitoringServer extends MonitoringServer {
// Process
res.setHeader('Content-Type', this.clientRegistry.contentType);
res.end(await this.clientRegistry.metrics());
+ for (const val of this.mapDatabaseMetric.values()) {
+ val.clear();
+ }
next();
// Trace Response
Logging.traceExpressResponse(req, res, next, ServerAction.MONITORING);
@@ -67,7 +72,6 @@ export default class PrometheusMonitoringServer extends MonitoringServer {
public createGaugeMetric(metricname : string, metrichelp : string, labelNames? : string[]) : Gauge {
let gaugeMetric : client.Gauge;
-
if (Array.isArray(labelNames)) {
gaugeMetric = new client.Gauge({
name: metricname,
@@ -80,10 +84,20 @@ export default class PrometheusMonitoringServer extends MonitoringServer {
help: metrichelp
});
}
-
this.mapGauge.set(metricname, gaugeMetric);
this.clientRegistry.registerMetric(gaugeMetric);
return gaugeMetric;
}
+ public getDatabaseMetric(metricname: string, suffix: number, metrichelp: string, labelNames: string[]) : DatabaseMonitoringMetric {
+ const key = metricname + '_' + suffix;
+ let dbMetric : DatabaseMonitoringMetric = this.mapDatabaseMetric.get(key);
+ if (dbMetric) {
+ return dbMetric;
+ }
+ dbMetric = new DatabaseMonitoringMetric(metricname,suffix,metrichelp,labelNames);
+ dbMetric.register(this.clientRegistry);
+ this.mapDatabaseMetric.set(key, dbMetric);
+ return dbMetric;
+ }
}

MODIFY
src/utils/Logging.ts
src/utils/Logging.ts
@@ -103,25 +103,12 @@ export default class Logging {
const labels = { tenant: tenant.subdomain, module: module, method: method };
const values = Object.values(labels).toString();
const hashCode = Utils.positiveHashcode(values);
- const gaugeDurationMetricName = 'mongodb' + '_Duration_' + hashCode;
- let gaugeDurationMetric:client.Gauge = global.monitoringServer.getGauge(gaugeDurationMetricName);
- if (!gaugeDurationMetric) {
- gaugeDurationMetric = this.createMetric(gaugeDurationMetricName);
- gaugeDurationMetric.labels(labels).set(executionDurationMillis);
- }
- const gaugeRequestSizeMetricName = 'mongodb' + '_RequestSize_' + hashCode;
- let gaugeRequestSizeMetric :client.Gauge = global.monitoringServer.getGauge(gaugeRequestSizeMetricName);
- if (!gaugeRequestSizeMetric) {
- gaugeRequestSizeMetric = this.createMetric(gaugeRequestSizeMetricName);
- gaugeRequestSizeMetric.labels(labels).set(sizeOfRequestDataKB);
- }
- const gaugeResponseSizeMetricName = 'mongodb' + '_ResponseSize_' + hashCode;
- let gaugeResponseSizeMetric :client.Gauge = global.monitoringServer.getGauge(gaugeResponseSizeMetricName);
- if (!gaugeResponseSizeMetric) {
- gaugeResponseSizeMetric = this.createMetric(gaugeResponseSizeMetricName);
- }
- gaugeResponseSizeMetric.labels(labels).set(sizeOfResponseDataKB);
- }
+ const durationMetric = global.monitoringServer.getDatabaseMetric('Duration', hashCode, 'db duration', Object.keys(labels));
+ durationMetric.setValue(labels, executionDurationMillis);
+ const requestSizeMetric = global.monitoringServer.getDatabaseMetric('RequestSize', hashCode, 'db duration', Object.keys(labels));
+ requestSizeMetric.setValue(labels, executionDurationMillis);
+ const responseSizeMetric = global.monitoringServer.getDatabaseMetric('ResponseSize', hashCode, 'db duration', Object.keys(labels));
+ responseSizeMetric.setValue(labels, executionDurationMillis);
await PerformanceStorage.savePerformanceRecord(
Utils.buildPerformanceRecord({
tenantSubdomain: tenant.subdomain,
@@ -135,6 +122,7 @@ export default class Logging {
);
}
}
+ }
public static traceNotificationStart(): number {

Added database monitoring metric