UNPKG

@christiangalsterer/mongodb-driver-prometheus-exporter

Version:
193 lines 11.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoDBDriverExporter = void 0; const prom_client_1 = require("prom-client"); const utils_1 = require("./utils"); const MILLISECONDS_IN_A_SECOND = 1000; const METRIC_INITIAL_ZERO = 0; class MongoDBDriverExporter { constructor(mongoClient, register, options) { this.defaultOptions = { // eslint-disable-next-line @typescript-eslint/no-magic-numbers mongodbDriverCommandsSecondsHistogramBuckets: [0.001, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10], // eslint-disable-next-line @typescript-eslint/no-magic-numbers waitQueueSecondsHistogramBuckets: [0.001, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10] }; this.MONGODB_DRIVER_POOL_SIZE = 'mongodb_driver_pool_size'; this.MONGODB_DRIVER_POOL_MIN = 'mongodb_driver_pool_min'; this.MONGODB_DRIVER_POOL_MAX = 'mongodb_driver_pool_max'; this.MONGODB_DRIVER_POOL_CHECKEDOUT = 'mongodb_driver_pool_checkedout'; this.MONGODB_DRIVER_POOL_WAITQUEUESIZE = 'mongodb_driver_pool_waitqueuesize'; this.MONGODB_DRIVER_POOL_WAITQUEUE_SECONDS = 'mongodb_driver_pool_waitqueue_seconds'; this.MONGODB_DRIVER_COMMANDS_SECONDS = 'mongodb_driver_commands_seconds'; this.mongoClient = mongoClient; this.register = register; this.options = { ...this.defaultOptions, ...options }; const prefix = options?.prefix ?? ''; const poolSizeMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_POOL_SIZE}`); this.poolSize = poolSizeMetric instanceof prom_client_1.Gauge ? poolSizeMetric : new prom_client_1.Gauge({ name: `${prefix}${this.MONGODB_DRIVER_POOL_SIZE}`, help: 'the current size of the connection pool, including idle and in-use members', labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['server_address'], this.options.defaultLabels), registers: [this.register] }); const minSizeMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_POOL_MIN}`); this.minSize = minSizeMetric instanceof prom_client_1.Gauge ? minSizeMetric : new prom_client_1.Gauge({ name: `${prefix}${this.MONGODB_DRIVER_POOL_MIN}`, help: 'the minimum size of the connection pool', labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['server_address'], this.options.defaultLabels), registers: [this.register] }); const maxSizeMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_POOL_MAX}`); this.maxSize = maxSizeMetric instanceof prom_client_1.Gauge ? maxSizeMetric : new prom_client_1.Gauge({ name: `${prefix}${this.MONGODB_DRIVER_POOL_MAX}`, help: 'the maximum size of the connection pool', labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['server_address'], this.options.defaultLabels), registers: [this.register] }); const checkedOutMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_POOL_CHECKEDOUT}`); this.checkedOut = checkedOutMetric instanceof prom_client_1.Gauge ? checkedOutMetric : new prom_client_1.Gauge({ name: `${prefix}${this.MONGODB_DRIVER_POOL_CHECKEDOUT}`, help: 'the count of connections that are currently in use', labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['server_address'], this.options.defaultLabels), registers: [this.register] }); const waitQueueSizeMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_POOL_WAITQUEUESIZE}`); this.waitQueueSize = waitQueueSizeMetric instanceof prom_client_1.Gauge ? waitQueueSizeMetric : new prom_client_1.Gauge({ name: `${prefix}${this.MONGODB_DRIVER_POOL_WAITQUEUESIZE}`, help: 'the current size of the wait queue for a connection from the pool', labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['server_address'], this.options.defaultLabels), registers: [this.register] }); const waitQueueSecondsMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_POOL_WAITQUEUE_SECONDS}`); this.waitQueueSeconds = waitQueueSecondsMetric instanceof prom_client_1.Histogram ? waitQueueSecondsMetric : new prom_client_1.Histogram({ name: `${prefix}${this.MONGODB_DRIVER_POOL_WAITQUEUE_SECONDS}`, help: 'Duration of waiting for a connection from the pool', buckets: this.options.waitQueueSecondsHistogramBuckets, labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['server_address', 'status'], this.options.defaultLabels), registers: [this.register] }); if (this.monitorCommands()) { const commandsMetric = this.register.getSingleMetric(`${prefix}${this.MONGODB_DRIVER_COMMANDS_SECONDS}`); this.commands = commandsMetric instanceof prom_client_1.Histogram ? commandsMetric : new prom_client_1.Histogram({ name: `${prefix}${this.MONGODB_DRIVER_COMMANDS_SECONDS}`, help: 'Timer of mongodb commands', buckets: this.options.mongodbDriverCommandsSecondsHistogramBuckets, labelNames: (0, utils_1.mergeLabelNamesWithStandardLabels)(['command', 'server_address', 'status'], this.options.defaultLabels), registers: [this.register] }); } } enableMetrics() { this.mongoClient.on('connectionPoolCreated', (event) => { this.onConnectionPoolCreated(event); }); this.mongoClient.on('connectionPoolClosed', (event) => { this.onConnectionPoolClosed(event); }); this.mongoClient.on('connectionCreated', (event) => { this.onConnectionCreated(event); }); this.mongoClient.on('connectionClosed', (event) => { this.onConnectionClosed(event); }); this.mongoClient.on('connectionCheckOutStarted', (event) => { this.onConnectionCheckOutStarted(event); }); this.mongoClient.on('connectionCheckedOut', (event) => { this.onConnectionCheckedOut(event); }); this.mongoClient.on('connectionCheckOutFailed', (event) => { this.onConnectionCheckOutFailed(event); }); this.mongoClient.on('connectionCheckedIn', (event) => { this.onConnectionCheckedIn(event); }); this.options.logger?.info('Successfully enabled connection pool metrics for the MongoDB Node.js driver.'); // command metrics if (this.monitorCommands()) { this.mongoClient.on('commandSucceeded', (event) => { this.onCommandSucceeded(event); }); this.mongoClient.on('commandFailed', (event) => { this.onCommandFailed(event); }); this.options.logger?.info('Successfully enabled command metrics for the MongoDB Node.js driver.'); } } monitorCommands() { return this.mongoClient.options.monitorCommands.valueOf(); } onConnectionPoolCreated(event) { this.poolSize.set((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels), METRIC_INITIAL_ZERO); this.minSize.set((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels), event.options.minPoolSize); this.maxSize.set((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels), event.options.maxPoolSize); this.checkedOut.set((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels), METRIC_INITIAL_ZERO); this.waitQueueSize.set((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels), METRIC_INITIAL_ZERO); } onConnectionCreated(event) { this.poolSize.inc((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); } onConnectionClosed(event) { this.poolSize.dec((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); } onConnectionCheckOutStarted(event) { this.waitQueueSize.inc((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); } onConnectionCheckedOut(event) { this.checkedOut.inc((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); this.waitQueueSize.dec((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (event.durationMS !== undefined) { // conditional observation for backward compatibility with `mongodb` <6.9.0 this.waitQueueSeconds.observe((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address, status: 'SUCCESS' }, this.options.defaultLabels), event.durationMS / MILLISECONDS_IN_A_SECOND); } } onConnectionCheckOutFailed(event) { this.waitQueueSize.dec((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (event.durationMS !== undefined) { // conditional observation for backward compatibility with `mongodb` <6.9.0 this.waitQueueSeconds.observe((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address, status: 'FAILED' }, this.options.defaultLabels), event.durationMS / MILLISECONDS_IN_A_SECOND); } } onConnectionCheckedIn(event) { this.checkedOut.dec((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels)); } onConnectionPoolClosed(event) { this.poolSize.set((0, utils_1.mergeLabelsWithStandardLabels)({ server_address: event.address }, this.options.defaultLabels), METRIC_INITIAL_ZERO); this.minSize.reset(); this.maxSize.reset(); this.checkedOut.reset(); this.waitQueueSize.reset(); } onCommandSucceeded(event) { this.commands.observe((0, utils_1.mergeLabelsWithStandardLabels)({ command: event.commandName, server_address: event.address, status: 'SUCCESS' }, this.options.defaultLabels), event.duration / MILLISECONDS_IN_A_SECOND); } onCommandFailed(event) { this.commands.observe((0, utils_1.mergeLabelsWithStandardLabels)({ command: event.commandName, server_address: event.address, status: 'FAILED' }, this.options.defaultLabels), event.duration / MILLISECONDS_IN_A_SECOND); } } exports.MongoDBDriverExporter = MongoDBDriverExporter; //# sourceMappingURL=mongoDBDriverExporter.js.map