@adalo/metrics 0.1.65 → 0.1.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/metricsQueueRedisClient.js +1 -1
- package/lib/metricsQueueRedisClient.js.map +1 -1
- package/lib/metricsRedisClient.d.ts.map +1 -1
- package/lib/metricsRedisClient.js +15 -1
- package/lib/metricsRedisClient.js.map +1 -1
- package/lib/redisUtils.d.ts +1 -1
- package/lib/redisUtils.d.ts.map +1 -1
- package/lib/redisUtils.js +10 -2
- package/lib/redisUtils.js.map +1 -1
- package/package.json +1 -1
- package/src/metricsQueueRedisClient.js +1 -1
- package/src/metricsRedisClient.js +13 -1
- package/src/redisUtils.js +14 -7
|
@@ -87,7 +87,7 @@ class QueueRedisMetricsClient extends RedisMetricsClient {
|
|
|
87
87
|
* @returns {object|any} Redis config object for BeeQueue or Redis client instance
|
|
88
88
|
*/
|
|
89
89
|
getConfigForDifferentRedis = () => {
|
|
90
|
-
if (isIORedis(this.
|
|
90
|
+
if (isIORedis(this.redisClient)) {
|
|
91
91
|
const {
|
|
92
92
|
host,
|
|
93
93
|
port,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metricsQueueRedisClient.js","names":["Queue","require","RedisMetricsClient","isIORedis","QueueRedisMetricsClient","constructor","redisClient","metricsConfig","getConfiguredQueueNames","process","env","METRICS_APP_REDIS_BQ","Error","allQueues","split","map","q","trim","filter","Boolean","length","Set","startupValidation","queueNames","console","info","error","message","queueCache","Map","queueJobsGauge","createGauge","name","help","labelNames","withDefaultLabels","_setCleanupHandlers","getConfigForDifferentRedis","client","host","port","db","password","options","collectSingleQueueMetrics","queueName","has","set","redis","isWorker","getEvents","sendEvents","queue","get","health","checkHealth","labels","getDefaultLabels","queue_name","status","waiting","active","succeeded","failed","delayed","warn","collectQueueMetrics","collectRedisMetrics","Promise","allSettled","gatewayPush","metricsLogValues","metricObjects","registry","getMetricsAsJSON","JSON","stringify","includes","startPush","intervalSec","_startPush","catch","err","on","cleanup","close","exit","module","exports"],"sources":["../src/metricsQueueRedisClient.js"],"sourcesContent":["const Queue = require('bee-queue')\nconst { RedisMetricsClient } = require('.')\nconst { isIORedis } = require('./redisUtils')\n\n/**\n * QueueRedisMetricsClient extends MetricsClient to collect\n * Redis and Bee Queue metrics periodically and push them to Prometheus Pushgateway.\n *\n * @extends RedisMetricsClient\n */\nclass QueueRedisMetricsClient extends RedisMetricsClient {\n /**\n * @param {Object} options\n * @param {any} options.redisClient - Redis client instance (required)\n * @param {string} [options.appName] - Application name (from MetricsClient)\n * @param {string} [options.dynoId] - Dyno/instance ID (from MetricsClient)\n * @param {string} [options.processType] - Process type (from MetricsClient)\n * @param {boolean} [options.enabled] - Enable metrics collection (from MetricsClient)\n * @param {boolean} [options.logValues] - Log metrics values (from MetricsClient)\n * @param {string} [options.pushgatewayUrl] - PushGateway URL (from MetricsClient)\n * @param {string} [options.pushgatewaySecret] - PushGateway secret token (from MetricsClient)\n * @param {number} [options.intervalSec] - Interval in seconds for pushing metrics (from MetricsClient)\n * @param {boolean} [options.removeOldMetrics] - Remove old metrics by service (from MetricsClient)\n * @param {boolean} [options.scripDefaultMetrics] - Skip default metrics creation (from MetricsClient)\n * @param {function} [options.startupValidation] - Function to validate startup (from MetricsClient)\n */\n constructor({ redisClient, metricsConfig = {} } = {}) {\n const getConfiguredQueueNames = () => {\n if (!process.env.METRICS_APP_REDIS_BQ) {\n throw new Error(\n 'No queues configured for monitoring. Set METRICS_APP_REDIS_BQ with comma-separated queue names'\n )\n }\n\n const allQueues = process.env.METRICS_APP_REDIS_BQ.split(',')\n .map(q => q.trim())\n .filter(Boolean)\n\n if (allQueues.length === 0) {\n throw new Error(\n 'METRICS_APP_REDIS_BQ is empty or contains only whitespace. ' +\n 'Example: METRICS_APP_REDIS_BQ=\"adalo-compile,adalo-migrations\"'\n )\n }\n\n return [...new Set(allQueues)]\n }\n\n const startupValidation = () => {\n try {\n const queueNames = getConfiguredQueueNames()\n console.info(\n `[queue-metrics] Queue & Redis metrics collection starting for ${queueNames.length} queues`\n )\n return true\n } catch (error) {\n console.error(`[queue-metrics] ❌ Cannot start: ${error.message}`)\n console.error(\n `[queue-metrics] 💡 Example: METRICS_APP_REDIS_BQ=\"adalo-compile,adalo-migrations\"`\n )\n console.error(\n `[queue-metrics] 💡 Optional: METRICS_QUEUE_INTERVAL_SEC=\"10\"`\n )\n console.error(`[queue-metrics] Skipping queue metrics collection`)\n return false\n }\n }\n\n super({\n ...metricsConfig,\n redisClient,\n startupValidation,\n })\n\n this.getConfiguredQueueNames = getConfiguredQueueNames\n this.startupValidation = startupValidation\n\n /** Cache for queue objects to avoid multiple connections */\n this.queueCache = new Map()\n\n /** Gauge for queue jobs by status */\n this.queueJobsGauge = this.createGauge({\n name: 'app_queue_jobs_count',\n help: 'Number of app jobs in the queue by status',\n labelNames: this.withDefaultLabels(['queue_name', 'status']),\n })\n\n this._setCleanupHandlers()\n }\n\n /**\n * Get the correct Redis configuration for a queue depending on the client type\n *\n * For ioredis, returns { host, port, db, password } because BeeQueue\n * cannot accept the full client instance.\n * For other Redis clients (v3/v4), returns the client instance directly.\n *\n * @returns {object|any} Redis config object for BeeQueue or Redis client instance\n */\n getConfigForDifferentRedis = () => {\n if (isIORedis(this.client)) {\n const { host, port, db, password } = this.redisClient.options\n return { host, port, db, password }\n }\n\n return this.redisClient\n }\n\n /**\n * Collect metrics for a single Bee Queue and set gauges\n * @param {string} queueName - Name of the queue\n * @returns {Promise<void>}\n */\n collectSingleQueueMetrics = async queueName => {\n try {\n if (!this.queueCache.has(queueName)) {\n this.queueCache.set(\n queueName,\n new Queue(queueName, {\n redis: this.getConfigForDifferentRedis(),\n isWorker: false,\n getEvents: false,\n sendEvents: false,\n })\n )\n }\n\n const queue = this.queueCache.get(queueName)\n const health = await queue.checkHealth()\n\n const labels = {\n ...this.getDefaultLabels(),\n queue_name: queueName,\n }\n\n this.queueJobsGauge.set(\n { ...labels, status: 'waiting' },\n health.waiting || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'active' },\n health.active || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'succeeded' },\n health.succeeded || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'failed' },\n health.failed || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'delayed' },\n health.delayed || 0\n )\n } catch (error) {\n console.warn(\n `[queue-metrics] Failed to collect metrics for queue ${queueName}:`,\n error.message\n )\n }\n }\n\n /**\n * Collect metrics for all queues and Redis, then push to Pushgateway\n * @returns {Promise<void>}\n */\n collectQueueMetrics = async () => {\n try {\n const queueNames = this.getConfiguredQueueNames()\n\n await this.collectRedisMetrics()\n await Promise.allSettled(\n queueNames.map(queueName => this.collectSingleQueueMetrics(queueName))\n )\n\n await this.gatewayPush()\n\n if (this.metricsLogValues) {\n const metricObjects = await this.registry.getMetricsAsJSON()\n console.info(\n `[queue-metrics] Collected metrics for ${queueNames.length} queues:`,\n JSON.stringify(metricObjects, null, 2)\n )\n }\n } catch (error) {\n if (\n error.message?.includes('No queues configured') ||\n error.message?.includes('METRICS_APP_REDIS_BQ')\n ) {\n console.error(\n `[queue-metrics] ❌ Configuration error: ${error.message}`\n )\n console.error(\n `[queue-metrics] 💡 Example config: METRICS_APP_REDIS_BQ=\"adalo-compile,adalo-migrations\"`\n )\n } else {\n console.error(\n `[queue-metrics] Failed to collect queue metrics: ${error.message}`\n )\n }\n throw error\n }\n }\n\n /**\n * Start periodic collection.\n * @param {number} [intervalSec=this.intervalSec] - Interval in seconds\n */\n startPush = (intervalSec = this.intervalSec) => {\n this._startPush(intervalSec, () => {\n this.collectQueueMetrics().catch(err => {\n console.error(\n `[queue-metrics] Failed to collect queue & Redis metrics:`,\n err\n )\n })\n })\n }\n\n _setCleanupHandlers = () => {\n process.on('SIGINT', this.cleanup)\n process.on('SIGTERM', this.cleanup)\n }\n\n /**\n * Cleanup queues and exit process.\n * @returns {Promise<void>}\n */\n cleanup = async () => {\n for (const [queueName, queue] of this.queueCache) {\n try {\n await queue.close()\n } catch (err) {\n console.error(`[queue-metrics] Error closing queue ${queueName}:`, err)\n }\n }\n process.exit(0)\n }\n}\n\nmodule.exports = { QueueRedisMetricsClient }\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"metricsQueueRedisClient.js","names":["Queue","require","RedisMetricsClient","isIORedis","QueueRedisMetricsClient","constructor","redisClient","metricsConfig","getConfiguredQueueNames","process","env","METRICS_APP_REDIS_BQ","Error","allQueues","split","map","q","trim","filter","Boolean","length","Set","startupValidation","queueNames","console","info","error","message","queueCache","Map","queueJobsGauge","createGauge","name","help","labelNames","withDefaultLabels","_setCleanupHandlers","getConfigForDifferentRedis","host","port","db","password","options","collectSingleQueueMetrics","queueName","has","set","redis","isWorker","getEvents","sendEvents","queue","get","health","checkHealth","labels","getDefaultLabels","queue_name","status","waiting","active","succeeded","failed","delayed","warn","collectQueueMetrics","collectRedisMetrics","Promise","allSettled","gatewayPush","metricsLogValues","metricObjects","registry","getMetricsAsJSON","JSON","stringify","includes","startPush","intervalSec","_startPush","catch","err","on","cleanup","close","exit","module","exports"],"sources":["../src/metricsQueueRedisClient.js"],"sourcesContent":["const Queue = require('bee-queue')\nconst { RedisMetricsClient } = require('.')\nconst { isIORedis } = require('./redisUtils')\n\n/**\n * QueueRedisMetricsClient extends MetricsClient to collect\n * Redis and Bee Queue metrics periodically and push them to Prometheus Pushgateway.\n *\n * @extends RedisMetricsClient\n */\nclass QueueRedisMetricsClient extends RedisMetricsClient {\n /**\n * @param {Object} options\n * @param {any} options.redisClient - Redis client instance (required)\n * @param {string} [options.appName] - Application name (from MetricsClient)\n * @param {string} [options.dynoId] - Dyno/instance ID (from MetricsClient)\n * @param {string} [options.processType] - Process type (from MetricsClient)\n * @param {boolean} [options.enabled] - Enable metrics collection (from MetricsClient)\n * @param {boolean} [options.logValues] - Log metrics values (from MetricsClient)\n * @param {string} [options.pushgatewayUrl] - PushGateway URL (from MetricsClient)\n * @param {string} [options.pushgatewaySecret] - PushGateway secret token (from MetricsClient)\n * @param {number} [options.intervalSec] - Interval in seconds for pushing metrics (from MetricsClient)\n * @param {boolean} [options.removeOldMetrics] - Remove old metrics by service (from MetricsClient)\n * @param {boolean} [options.scripDefaultMetrics] - Skip default metrics creation (from MetricsClient)\n * @param {function} [options.startupValidation] - Function to validate startup (from MetricsClient)\n */\n constructor({ redisClient, metricsConfig = {} } = {}) {\n const getConfiguredQueueNames = () => {\n if (!process.env.METRICS_APP_REDIS_BQ) {\n throw new Error(\n 'No queues configured for monitoring. Set METRICS_APP_REDIS_BQ with comma-separated queue names'\n )\n }\n\n const allQueues = process.env.METRICS_APP_REDIS_BQ.split(',')\n .map(q => q.trim())\n .filter(Boolean)\n\n if (allQueues.length === 0) {\n throw new Error(\n 'METRICS_APP_REDIS_BQ is empty or contains only whitespace. ' +\n 'Example: METRICS_APP_REDIS_BQ=\"adalo-compile,adalo-migrations\"'\n )\n }\n\n return [...new Set(allQueues)]\n }\n\n const startupValidation = () => {\n try {\n const queueNames = getConfiguredQueueNames()\n console.info(\n `[queue-metrics] Queue & Redis metrics collection starting for ${queueNames.length} queues`\n )\n return true\n } catch (error) {\n console.error(`[queue-metrics] ❌ Cannot start: ${error.message}`)\n console.error(\n `[queue-metrics] 💡 Example: METRICS_APP_REDIS_BQ=\"adalo-compile,adalo-migrations\"`\n )\n console.error(\n `[queue-metrics] 💡 Optional: METRICS_QUEUE_INTERVAL_SEC=\"10\"`\n )\n console.error(`[queue-metrics] Skipping queue metrics collection`)\n return false\n }\n }\n\n super({\n ...metricsConfig,\n redisClient,\n startupValidation,\n })\n\n this.getConfiguredQueueNames = getConfiguredQueueNames\n this.startupValidation = startupValidation\n\n /** Cache for queue objects to avoid multiple connections */\n this.queueCache = new Map()\n\n /** Gauge for queue jobs by status */\n this.queueJobsGauge = this.createGauge({\n name: 'app_queue_jobs_count',\n help: 'Number of app jobs in the queue by status',\n labelNames: this.withDefaultLabels(['queue_name', 'status']),\n })\n\n this._setCleanupHandlers()\n }\n\n /**\n * Get the correct Redis configuration for a queue depending on the client type\n *\n * For ioredis, returns { host, port, db, password } because BeeQueue\n * cannot accept the full client instance.\n * For other Redis clients (v3/v4), returns the client instance directly.\n *\n * @returns {object|any} Redis config object for BeeQueue or Redis client instance\n */\n getConfigForDifferentRedis = () => {\n if (isIORedis(this.redisClient)) {\n const { host, port, db, password } = this.redisClient.options\n return { host, port, db, password }\n }\n\n return this.redisClient\n }\n\n /**\n * Collect metrics for a single Bee Queue and set gauges\n * @param {string} queueName - Name of the queue\n * @returns {Promise<void>}\n */\n collectSingleQueueMetrics = async queueName => {\n try {\n if (!this.queueCache.has(queueName)) {\n this.queueCache.set(\n queueName,\n new Queue(queueName, {\n redis: this.getConfigForDifferentRedis(),\n isWorker: false,\n getEvents: false,\n sendEvents: false,\n })\n )\n }\n\n const queue = this.queueCache.get(queueName)\n const health = await queue.checkHealth()\n\n const labels = {\n ...this.getDefaultLabels(),\n queue_name: queueName,\n }\n\n this.queueJobsGauge.set(\n { ...labels, status: 'waiting' },\n health.waiting || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'active' },\n health.active || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'succeeded' },\n health.succeeded || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'failed' },\n health.failed || 0\n )\n this.queueJobsGauge.set(\n { ...labels, status: 'delayed' },\n health.delayed || 0\n )\n } catch (error) {\n console.warn(\n `[queue-metrics] Failed to collect metrics for queue ${queueName}:`,\n error.message\n )\n }\n }\n\n /**\n * Collect metrics for all queues and Redis, then push to Pushgateway\n * @returns {Promise<void>}\n */\n collectQueueMetrics = async () => {\n try {\n const queueNames = this.getConfiguredQueueNames()\n\n await this.collectRedisMetrics()\n await Promise.allSettled(\n queueNames.map(queueName => this.collectSingleQueueMetrics(queueName))\n )\n\n await this.gatewayPush()\n\n if (this.metricsLogValues) {\n const metricObjects = await this.registry.getMetricsAsJSON()\n console.info(\n `[queue-metrics] Collected metrics for ${queueNames.length} queues:`,\n JSON.stringify(metricObjects, null, 2)\n )\n }\n } catch (error) {\n if (\n error.message?.includes('No queues configured') ||\n error.message?.includes('METRICS_APP_REDIS_BQ')\n ) {\n console.error(\n `[queue-metrics] ❌ Configuration error: ${error.message}`\n )\n console.error(\n `[queue-metrics] 💡 Example config: METRICS_APP_REDIS_BQ=\"adalo-compile,adalo-migrations\"`\n )\n } else {\n console.error(\n `[queue-metrics] Failed to collect queue metrics: ${error.message}`\n )\n }\n throw error\n }\n }\n\n /**\n * Start periodic collection.\n * @param {number} [intervalSec=this.intervalSec] - Interval in seconds\n */\n startPush = (intervalSec = this.intervalSec) => {\n this._startPush(intervalSec, () => {\n this.collectQueueMetrics().catch(err => {\n console.error(\n `[queue-metrics] Failed to collect queue & Redis metrics:`,\n err\n )\n })\n })\n }\n\n _setCleanupHandlers = () => {\n process.on('SIGINT', this.cleanup)\n process.on('SIGTERM', this.cleanup)\n }\n\n /**\n * Cleanup queues and exit process.\n * @returns {Promise<void>}\n */\n cleanup = async () => {\n for (const [queueName, queue] of this.queueCache) {\n try {\n await queue.close()\n } catch (err) {\n console.error(`[queue-metrics] Error closing queue ${queueName}:`, err)\n }\n }\n process.exit(0)\n }\n}\n\nmodule.exports = { QueueRedisMetricsClient }\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metricsRedisClient.d.ts","sourceRoot":"","sources":["../src/metricsRedisClient.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"metricsRedisClient.d.ts","sourceRoot":"","sources":["../src/metricsRedisClient.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH;IACE;;;;;;;;;;;;;;OAcG;IACH;QAbwB,WAAW,EAAxB,GAAG;QACc,OAAO;QACP,MAAM;QACN,WAAW;QACV,OAAO;QACP,SAAS;QACV,cAAc;QACd,iBAAiB;QACjB,WAAW;QACV,gBAAgB;QAChB,mBAAmB;QAClB,iBAAiB;OAwC9C;IAzBC,oCAAoC;IACpC,iBAA8B;IAE9B,yCAAyC;IACzC,2DAIE;IAEF,mCAAmC;IACnC,sDAIE;IAEF,sCAAsC;IACtC,qDAIE;IAKJ,6CA2CC;IAED;;;OAGG;IACH,2BAFa,QAAQ,IAAI,CAAC,CAyDzB;IAED;;;OAGG;IACH,wBAFa,QAAQ,IAAI,CAAC,CAoBzB;IAED;;;OAGG;IACH,sDAMC;CA2BF"}
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
const {
|
|
4
4
|
MetricsClient
|
|
5
5
|
} = require('.');
|
|
6
|
+
const {
|
|
7
|
+
isIORedis
|
|
8
|
+
} = require('./redisUtils');
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* RedisMetricsClient extends MetricsClient to collect
|
|
@@ -68,6 +71,17 @@ class RedisMetricsClient extends MetricsClient {
|
|
|
68
71
|
console.log('Redis client constructor name:', this.redisClient.constructor.name);
|
|
69
72
|
console.log('Redis client info function:', this.redisClient.info);
|
|
70
73
|
|
|
74
|
+
// node-redis ioredis
|
|
75
|
+
if (isIORedis(this.redisClient)) {
|
|
76
|
+
console.log('Detected node-redis ioredis');
|
|
77
|
+
try {
|
|
78
|
+
const result = await this.redisClient.info(section);
|
|
79
|
+
return result;
|
|
80
|
+
} catch (err) {
|
|
81
|
+
throw new Error(`Failed to get Redis INFO: ${err.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
71
85
|
// node-redis v3 (uses callback)
|
|
72
86
|
if (typeof this.redisClient.send_command === 'function') {
|
|
73
87
|
console.log('Detected node-redis v3');
|
|
@@ -80,7 +94,7 @@ class RedisMetricsClient extends MetricsClient {
|
|
|
80
94
|
|
|
81
95
|
// node-redis v4 or ioredis (info returns Promise)
|
|
82
96
|
if (typeof this.redisClient.info === 'function') {
|
|
83
|
-
console.log('Detected node-redis v4
|
|
97
|
+
console.log('Detected node-redis v4');
|
|
84
98
|
try {
|
|
85
99
|
const result = await this.redisClient.info(section);
|
|
86
100
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metricsRedisClient.js","names":["MetricsClient","require","RedisMetricsClient","constructor","redisClient","metricsConfig","intervalSec","parseInt","process","env","METRICS_QUEUE_INTERVAL_SEC","scripDefaultMetrics","processType","redisConnectionsGauge","createGauge","name","help","labelNames","withDefaultLabels","redisMemoryGauge","redisStatsGauge","_setCleanupHandlers","getRedisInfo","section","Error","console","log","info","send_command","Promise","resolve","reject","err","result","message","collectRedisMetrics","clientsInfo","memoryInfo","statsInfo","all","labels","getDefaultLabels","parseRedisInfo","infoStr","Object","fromEntries","split","filter","line","startsWith","map","parts","length","clients","memory","stats","connected_clients","set","connection_type","used_memory","memory_type","maxmemory","instantaneous_ops_per_sec","operation","error","warn","pushRedisMetrics","gatewayPush","metricsLogValues","metricObjects","registry","getMetricsAsJSON","JSON","stringify","startPush","_startPush","catch","cleanup","quit","disconnect","exit","on","module","exports"],"sources":["../src/metricsRedisClient.js"],"sourcesContent":["const { MetricsClient } = require('.')\n\n/**\n * RedisMetricsClient extends MetricsClient to collect\n * Redis metrics periodically and push them to Prometheus Pushgateway.\n *\n * @extends MetricsClient\n */\nclass RedisMetricsClient extends MetricsClient {\n /**\n * @param {Object} options\n * @param {any} options.redisClient - Redis client instance (required)\n * @param {string} [options.appName] - Application name (from MetricsClient)\n * @param {string} [options.dynoId] - Dyno/instance ID (from MetricsClient)\n * @param {string} [options.processType] - Process type (from MetricsClient)\n * @param {boolean} [options.enabled] - Enable metrics collection (from MetricsClient)\n * @param {boolean} [options.logValues] - Log metrics values (from MetricsClient)\n * @param {string} [options.pushgatewayUrl] - PushGateway URL (from MetricsClient)\n * @param {string} [options.pushgatewaySecret] - PushGateway secret token (from MetricsClient)\n * @param {number} [options.intervalSec] - Interval in seconds for pushing metrics (from MetricsClient)\n * @param {boolean} [options.removeOldMetrics] - Remove old metrics by service (from MetricsClient)\n * @param {boolean} [options.scripDefaultMetrics] - Skip default metrics creation (from MetricsClient)\n * @param {function} [options.startupValidation] - Function to validate startup (from MetricsClient)\n */\n constructor({ redisClient, ...metricsConfig } = {}) {\n const intervalSec =\n metricsConfig.intervalSec ||\n parseInt(process.env.METRICS_QUEUE_INTERVAL_SEC || '', 10) ||\n 5\n\n super({\n ...metricsConfig,\n scripDefaultMetrics: true,\n processType: metricsConfig.processType || 'redis-metrics',\n intervalSec,\n })\n\n /** Redis client used for metrics */\n this.redisClient = redisClient\n\n /** Gauge for Redis client connections */\n this.redisConnectionsGauge = this.createGauge({\n name: 'app_redis_connections_count',\n help: 'Number of Redis client connections',\n labelNames: this.withDefaultLabels(['connection_type']),\n })\n\n /** Gauge for Redis memory usage */\n this.redisMemoryGauge = this.createGauge({\n name: 'app_redis_memory_bytes',\n help: 'Redis memory usage in bytes',\n labelNames: this.withDefaultLabels(['memory_type']),\n })\n\n /** Gauge for Redis operation stats */\n this.redisStatsGauge = this.createGauge({\n name: 'app_redis_stats_total',\n help: 'Redis operation statistics',\n labelNames: this.withDefaultLabels(['operation']),\n })\n\n this._setCleanupHandlers()\n }\n\n getRedisInfo = async section => {\n if (!this.redisClient) throw new Error('Redis client not provided')\n\n console.log(\n 'Redis client constructor name:',\n this.redisClient.constructor.name\n )\n console.log('Redis client info function:', this.redisClient.info)\n\n // node-redis v3 (uses callback)\n if (typeof this.redisClient.send_command === 'function') {\n console.log('Detected node-redis v3')\n return new Promise((resolve, reject) => {\n this.redisClient.info(section, (err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n }\n\n // node-redis v4 or ioredis (info returns Promise)\n if (typeof this.redisClient.info === 'function') {\n console.log('Detected node-redis v4 or ioredis')\n try {\n const result = await this.redisClient.info(section)\n return result\n } catch (err) {\n throw new Error(`Failed to get Redis INFO: ${err.message}`)\n }\n }\n\n throw new Error('Unsupported Redis client type')\n }\n\n /**\n * Collect basic Redis INFO metrics: clients, memory, stats\n * @returns {Promise<void>}\n */\n collectRedisMetrics = async () => {\n try {\n const [clientsInfo, memoryInfo, statsInfo] = await Promise.all([\n this.getRedisInfo('clients'),\n this.getRedisInfo('memory'),\n this.getRedisInfo('stats'),\n ])\n\n const labels = this.getDefaultLabels()\n\n const parseRedisInfo = infoStr =>\n Object.fromEntries(\n infoStr\n .split('\\r\\n')\n .filter(line => line && !line.startsWith('#'))\n .map(line => line.split(':', 2))\n .filter(parts => parts.length === 2 && parts[0] && parts[1])\n )\n\n const clients = parseRedisInfo(clientsInfo)\n const memory = parseRedisInfo(memoryInfo)\n const stats = parseRedisInfo(statsInfo)\n\n if (clients.connected_clients) {\n this.redisConnectionsGauge.set(\n { ...labels, connection_type: 'connected' },\n parseInt(clients.connected_clients, 10) || 0\n )\n }\n\n if (memory.used_memory) {\n this.redisMemoryGauge.set(\n { ...labels, memory_type: 'used' },\n parseInt(memory.used_memory, 10) || 0\n )\n }\n if (memory.maxmemory) {\n this.redisMemoryGauge.set(\n { ...labels, memory_type: 'max' },\n parseInt(memory.maxmemory, 10) || 0\n )\n }\n\n if (stats.instantaneous_ops_per_sec) {\n this.redisStatsGauge.set(\n { ...labels, operation: 'ops_per_sec' },\n parseInt(stats.instantaneous_ops_per_sec, 10) || 0\n )\n }\n } catch (error) {\n console.warn(\n `[redis-metrics] Failed to collect Redis metrics:`,\n error.message\n )\n }\n }\n\n /**\n * Collect metrics for all Redis and push to Prometheus Pushgateway\n * @returns {Promise<void>}\n */\n pushRedisMetrics = async () => {\n try {\n await this.collectRedisMetrics()\n await this.gatewayPush()\n\n if (this.metricsLogValues) {\n const metricObjects = await this.registry.getMetricsAsJSON()\n console.info(\n `[redis-metrics] Collected metrics for Redis`,\n JSON.stringify(metricObjects, null, 2)\n )\n }\n } catch (error) {\n console.error(\n `[redis-metrics] Failed to collect Redis metrics: ${error.message}`\n )\n throw error\n }\n }\n\n /**\n * Start periodic collection.\n * @param {number} [intervalSec=this.intervalSec] - Interval in seconds\n */\n startPush = (intervalSec = this.intervalSec) => {\n this._startPush(intervalSec, () => {\n this.pushRedisMetrics().catch(err => {\n console.error(`[redis-metrics] Failed to push Redis metrics:`, err)\n })\n })\n }\n\n /**\n * Cleanup Redis client and exit process.\n * @returns {Promise<void>}\n */\n cleanup = async () => {\n try {\n if (!this.redisClient) return\n\n if (typeof this.redisClient.quit === 'function') {\n // node-redis v3 or v4\n await this.redisClient.quit()\n } else if (typeof this.redisClient.disconnect === 'function') {\n // ioredis\n await this.redisClient.disconnect()\n }\n } catch (err) {\n console.error('[redis-metrics] Error closing Redis client:', err)\n }\n process.exit(0)\n }\n\n _setCleanupHandlers = () => {\n process.on('SIGINT', this.cleanup)\n process.on('SIGTERM', this.cleanup)\n }\n}\n\nmodule.exports = { RedisMetricsClient }\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"metricsRedisClient.js","names":["MetricsClient","require","isIORedis","RedisMetricsClient","constructor","redisClient","metricsConfig","intervalSec","parseInt","process","env","METRICS_QUEUE_INTERVAL_SEC","scripDefaultMetrics","processType","redisConnectionsGauge","createGauge","name","help","labelNames","withDefaultLabels","redisMemoryGauge","redisStatsGauge","_setCleanupHandlers","getRedisInfo","section","Error","console","log","info","result","err","message","send_command","Promise","resolve","reject","collectRedisMetrics","clientsInfo","memoryInfo","statsInfo","all","labels","getDefaultLabels","parseRedisInfo","infoStr","Object","fromEntries","split","filter","line","startsWith","map","parts","length","clients","memory","stats","connected_clients","set","connection_type","used_memory","memory_type","maxmemory","instantaneous_ops_per_sec","operation","error","warn","pushRedisMetrics","gatewayPush","metricsLogValues","metricObjects","registry","getMetricsAsJSON","JSON","stringify","startPush","_startPush","catch","cleanup","quit","disconnect","exit","on","module","exports"],"sources":["../src/metricsRedisClient.js"],"sourcesContent":["const { MetricsClient } = require('.')\nconst { isIORedis } = require('./redisUtils')\n\n/**\n * RedisMetricsClient extends MetricsClient to collect\n * Redis metrics periodically and push them to Prometheus Pushgateway.\n *\n * @extends MetricsClient\n */\nclass RedisMetricsClient extends MetricsClient {\n /**\n * @param {Object} options\n * @param {any} options.redisClient - Redis client instance (required)\n * @param {string} [options.appName] - Application name (from MetricsClient)\n * @param {string} [options.dynoId] - Dyno/instance ID (from MetricsClient)\n * @param {string} [options.processType] - Process type (from MetricsClient)\n * @param {boolean} [options.enabled] - Enable metrics collection (from MetricsClient)\n * @param {boolean} [options.logValues] - Log metrics values (from MetricsClient)\n * @param {string} [options.pushgatewayUrl] - PushGateway URL (from MetricsClient)\n * @param {string} [options.pushgatewaySecret] - PushGateway secret token (from MetricsClient)\n * @param {number} [options.intervalSec] - Interval in seconds for pushing metrics (from MetricsClient)\n * @param {boolean} [options.removeOldMetrics] - Remove old metrics by service (from MetricsClient)\n * @param {boolean} [options.scripDefaultMetrics] - Skip default metrics creation (from MetricsClient)\n * @param {function} [options.startupValidation] - Function to validate startup (from MetricsClient)\n */\n constructor({ redisClient, ...metricsConfig } = {}) {\n const intervalSec =\n metricsConfig.intervalSec ||\n parseInt(process.env.METRICS_QUEUE_INTERVAL_SEC || '', 10) ||\n 5\n\n super({\n ...metricsConfig,\n scripDefaultMetrics: true,\n processType: metricsConfig.processType || 'redis-metrics',\n intervalSec,\n })\n\n /** Redis client used for metrics */\n this.redisClient = redisClient\n\n /** Gauge for Redis client connections */\n this.redisConnectionsGauge = this.createGauge({\n name: 'app_redis_connections_count',\n help: 'Number of Redis client connections',\n labelNames: this.withDefaultLabels(['connection_type']),\n })\n\n /** Gauge for Redis memory usage */\n this.redisMemoryGauge = this.createGauge({\n name: 'app_redis_memory_bytes',\n help: 'Redis memory usage in bytes',\n labelNames: this.withDefaultLabels(['memory_type']),\n })\n\n /** Gauge for Redis operation stats */\n this.redisStatsGauge = this.createGauge({\n name: 'app_redis_stats_total',\n help: 'Redis operation statistics',\n labelNames: this.withDefaultLabels(['operation']),\n })\n\n this._setCleanupHandlers()\n }\n\n getRedisInfo = async section => {\n if (!this.redisClient) throw new Error('Redis client not provided')\n\n console.log(\n 'Redis client constructor name:',\n this.redisClient.constructor.name\n )\n console.log('Redis client info function:', this.redisClient.info)\n\n // node-redis ioredis\n if (isIORedis(this.redisClient)) {\n console.log('Detected node-redis ioredis')\n try {\n const result = await this.redisClient.info(section)\n return result\n } catch (err) {\n throw new Error(`Failed to get Redis INFO: ${err.message}`)\n }\n }\n\n // node-redis v3 (uses callback)\n if (typeof this.redisClient.send_command === 'function') {\n console.log('Detected node-redis v3')\n return new Promise((resolve, reject) => {\n this.redisClient.info(section, (err, result) => {\n if (err) reject(err)\n else resolve(result)\n })\n })\n }\n\n // node-redis v4 or ioredis (info returns Promise)\n if (typeof this.redisClient.info === 'function') {\n console.log('Detected node-redis v4')\n try {\n const result = await this.redisClient.info(section)\n return result\n } catch (err) {\n throw new Error(`Failed to get Redis INFO: ${err.message}`)\n }\n }\n\n throw new Error('Unsupported Redis client type')\n }\n\n /**\n * Collect basic Redis INFO metrics: clients, memory, stats\n * @returns {Promise<void>}\n */\n collectRedisMetrics = async () => {\n try {\n const [clientsInfo, memoryInfo, statsInfo] = await Promise.all([\n this.getRedisInfo('clients'),\n this.getRedisInfo('memory'),\n this.getRedisInfo('stats'),\n ])\n\n const labels = this.getDefaultLabels()\n\n const parseRedisInfo = infoStr =>\n Object.fromEntries(\n infoStr\n .split('\\r\\n')\n .filter(line => line && !line.startsWith('#'))\n .map(line => line.split(':', 2))\n .filter(parts => parts.length === 2 && parts[0] && parts[1])\n )\n\n const clients = parseRedisInfo(clientsInfo)\n const memory = parseRedisInfo(memoryInfo)\n const stats = parseRedisInfo(statsInfo)\n\n if (clients.connected_clients) {\n this.redisConnectionsGauge.set(\n { ...labels, connection_type: 'connected' },\n parseInt(clients.connected_clients, 10) || 0\n )\n }\n\n if (memory.used_memory) {\n this.redisMemoryGauge.set(\n { ...labels, memory_type: 'used' },\n parseInt(memory.used_memory, 10) || 0\n )\n }\n if (memory.maxmemory) {\n this.redisMemoryGauge.set(\n { ...labels, memory_type: 'max' },\n parseInt(memory.maxmemory, 10) || 0\n )\n }\n\n if (stats.instantaneous_ops_per_sec) {\n this.redisStatsGauge.set(\n { ...labels, operation: 'ops_per_sec' },\n parseInt(stats.instantaneous_ops_per_sec, 10) || 0\n )\n }\n } catch (error) {\n console.warn(\n `[redis-metrics] Failed to collect Redis metrics:`,\n error.message\n )\n }\n }\n\n /**\n * Collect metrics for all Redis and push to Prometheus Pushgateway\n * @returns {Promise<void>}\n */\n pushRedisMetrics = async () => {\n try {\n await this.collectRedisMetrics()\n await this.gatewayPush()\n\n if (this.metricsLogValues) {\n const metricObjects = await this.registry.getMetricsAsJSON()\n console.info(\n `[redis-metrics] Collected metrics for Redis`,\n JSON.stringify(metricObjects, null, 2)\n )\n }\n } catch (error) {\n console.error(\n `[redis-metrics] Failed to collect Redis metrics: ${error.message}`\n )\n throw error\n }\n }\n\n /**\n * Start periodic collection.\n * @param {number} [intervalSec=this.intervalSec] - Interval in seconds\n */\n startPush = (intervalSec = this.intervalSec) => {\n this._startPush(intervalSec, () => {\n this.pushRedisMetrics().catch(err => {\n console.error(`[redis-metrics] Failed to push Redis metrics:`, err)\n })\n })\n }\n\n /**\n * Cleanup Redis client and exit process.\n * @returns {Promise<void>}\n */\n cleanup = async () => {\n try {\n if (!this.redisClient) return\n\n if (typeof this.redisClient.quit === 'function') {\n // node-redis v3 or v4\n await this.redisClient.quit()\n } else if (typeof this.redisClient.disconnect === 'function') {\n // ioredis\n await this.redisClient.disconnect()\n }\n } catch (err) {\n console.error('[redis-metrics] Error closing Redis client:', err)\n }\n process.exit(0)\n }\n\n _setCleanupHandlers = () => {\n process.on('SIGINT', this.cleanup)\n process.on('SIGTERM', this.cleanup)\n }\n}\n\nmodule.exports = { RedisMetricsClient }\n"],"mappings":"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","ignoreList":[]}
|
package/lib/redisUtils.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export function createSetClientNameForIoredis(defaultAppName?: string | undefine
|
|
|
23
23
|
* Check if a Redis client is an ioredis instance
|
|
24
24
|
*
|
|
25
25
|
* @param {any} client - Redis client instance
|
|
26
|
-
* @returns {boolean} True if the client is ioredis
|
|
26
|
+
* @returns {boolean} True if the client is ioredis
|
|
27
27
|
*/
|
|
28
28
|
export function isIORedis(client: any): boolean;
|
|
29
29
|
//# sourceMappingURL=redisUtils.d.ts.map
|
package/lib/redisUtils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redisUtils.d.ts","sourceRoot":"","sources":["../src/redisUtils.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,6FAFsB,GAAG,QAAQ,MAAM,KAAK,IAAI,CAuB/C;AA4BD;;;;;GAKG;AACH,6FAFsB,GAAG,QAAQ,MAAM,KAAK,IAAI,CAsB/C;AApDD;;;;;GAKG;AACH,6FAFsB,GAAG,QAAQ,MAAM,KAAK,IAAI,CAoB/C;AA8BD;;;;;GAKG;AACH,kCAHW,GAAG,GACD,OAAO,
|
|
1
|
+
{"version":3,"file":"redisUtils.d.ts","sourceRoot":"","sources":["../src/redisUtils.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,6FAFsB,GAAG,QAAQ,MAAM,KAAK,IAAI,CAuB/C;AA4BD;;;;;GAKG;AACH,6FAFsB,GAAG,QAAQ,MAAM,KAAK,IAAI,CAsB/C;AApDD;;;;;GAKG;AACH,6FAFsB,GAAG,QAAQ,MAAM,KAAK,IAAI,CAoB/C;AA8BD;;;;;GAKG;AACH,kCAHW,GAAG,GACD,OAAO,CAiBnB"}
|
package/lib/redisUtils.js
CHANGED
|
@@ -73,10 +73,18 @@ const createSetClientNameForRedisV4 = (defaultAppName = 'undefined-app') => {
|
|
|
73
73
|
* Check if a Redis client is an ioredis instance
|
|
74
74
|
*
|
|
75
75
|
* @param {any} client - Redis client instance
|
|
76
|
-
* @returns {boolean} True if the client is ioredis
|
|
76
|
+
* @returns {boolean} True if the client is ioredis
|
|
77
77
|
*/
|
|
78
78
|
const isIORedis = client => {
|
|
79
|
-
|
|
79
|
+
const result = client && typeof client.sendCommand === 'function' && typeof client.disconnect === 'function' && client.options !== undefined;
|
|
80
|
+
console.log('[debug] isIORedis client.sendCommand:', client.sendCommand);
|
|
81
|
+
console.log('[debug] isIORedis client.sendCommand === \'function\':', typeof client.sendCommand === 'function');
|
|
82
|
+
console.log('[debug] isIORedis client.disconnect:', client.disconnect);
|
|
83
|
+
console.log('[debug] isIORedis client.disconnect === \'function\':', typeof client.disconnect === 'function');
|
|
84
|
+
console.log('[debug] isIORedis client.options:', client.options);
|
|
85
|
+
console.log('[debug] isIORedis client.options !== undefined:', client.options !== undefined);
|
|
86
|
+
console.log('[debug] isIORedis check:', result, 'constructor:', client?.constructor?.name);
|
|
87
|
+
return result;
|
|
80
88
|
};
|
|
81
89
|
module.exports = {
|
|
82
90
|
createSetClientNameForRedisV3,
|
package/lib/redisUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redisUtils.js","names":["createSetClientNameForRedisV3","defaultAppName","client","name","appName","process","env","METRICS_APP_NAME","dyno","BUILD_DYNO_PROCESS_TYPE","NODE_ENV","on","send_command","err","console","error","log","pid","createSetClientNameForIoredis","once","call","then","catch","createSetClientNameForRedisV4","sendCommand","isIORedis","
|
|
1
|
+
{"version":3,"file":"redisUtils.js","names":["createSetClientNameForRedisV3","defaultAppName","client","name","appName","process","env","METRICS_APP_NAME","dyno","BUILD_DYNO_PROCESS_TYPE","NODE_ENV","on","send_command","err","console","error","log","pid","createSetClientNameForIoredis","once","call","then","catch","createSetClientNameForRedisV4","sendCommand","isIORedis","result","disconnect","options","undefined","constructor","module","exports"],"sources":["../src/redisUtils.js"],"sourcesContent":["/**\n * Creates a configured setClientName function for node-redis v3.\n *\n * @param {string} [defaultAppName='undefined-app'] - Fallback app name if METRICS_APP_NAME is not set.\n * @returns {(client: any, name: string) => void}\n */\nconst createSetClientNameForRedisV3 = (defaultAppName = 'undefined-app') => {\n return (client, name) => {\n const appName = process.env.METRICS_APP_NAME || defaultAppName\n const dyno = process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined-dyno'\n\n if (process.env.NODE_ENV !== 'test') {\n client.on('connect', () => {\n client.send_command(\n 'CLIENT',\n ['SETNAME', `${appName}:${dyno}:${name}`],\n err => {\n if (err) {\n console.error(`Failed to set client name for ${name}:`, err)\n } else {\n console.log(`Connected to Redis for pid:${process.pid} (${name})`)\n }\n }\n )\n })\n }\n }\n}\n\n/**\n * Creates a function to set Redis client name for ioredis.\n *\n * @param {string} [defaultAppName='undefined-app']\n * @returns {(client: any, name: string) => void}\n */\nconst createSetClientNameForIoredis = (defaultAppName = 'undefined-app') => {\n return (client, name) => {\n const appName = process.env.METRICS_APP_NAME || defaultAppName\n const dyno = process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined-dyno'\n\n if (process.env.NODE_ENV !== 'test') {\n client.once('connect', () => {\n client\n .call('CLIENT', ['SETNAME', `${appName}:${dyno}:${name}`])\n .then(() => {\n console.log(`Connected to Redis for pid:${process.pid} (${name})`)\n })\n .catch(err => {\n console.error(`Failed to set client name for ${name}:`, err)\n })\n })\n }\n }\n}\n\n/**\n * Creates a function to set Redis client name for node-redis v4.\n *\n * @param {string} [defaultAppName='undefined-app']\n * @returns {(client: any, name: string) => void}\n */\nconst createSetClientNameForRedisV4 = (defaultAppName = 'undefined-app') => {\n return (client, name) => {\n const appName = process.env.METRICS_APP_NAME || defaultAppName\n const dyno = process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined-dyno'\n\n if (process.env.NODE_ENV !== 'test') {\n client.on('ready', async () => {\n try {\n await client.sendCommand([\n 'CLIENT',\n 'SETNAME',\n `${appName}:${dyno}:${name}`,\n ])\n console.log(`Connected to Redis for pid:${process.pid} (${name})`)\n } catch (err) {\n console.error(`Failed to set client name for ${name}:`, err)\n }\n })\n }\n }\n}\n\n/**\n * Check if a Redis client is an ioredis instance\n *\n * @param {any} client - Redis client instance\n * @returns {boolean} True if the client is ioredis\n */\nconst isIORedis = client => {\n const result =\n client &&\n typeof client.sendCommand === 'function' &&\n typeof client.disconnect === 'function' &&\n client.options !== undefined;\n console.log('[debug] isIORedis client.sendCommand:', client.sendCommand);\n console.log('[debug] isIORedis client.sendCommand === \\'function\\':', typeof client.sendCommand === 'function');\n console.log('[debug] isIORedis client.disconnect:', client.disconnect);\n console.log('[debug] isIORedis client.disconnect === \\'function\\':', typeof client.disconnect === 'function');\n console.log('[debug] isIORedis client.options:', client.options);\n console.log('[debug] isIORedis client.options !== undefined:', client.options !== undefined);\n\n console.log('[debug] isIORedis check:', result, 'constructor:', client?.constructor?.name);\n return result;\n};\n\nmodule.exports = {\n createSetClientNameForRedisV3,\n createSetClientNameForRedisV4,\n createSetClientNameForIoredis,\n isIORedis,\n}\n"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMA,6BAA6B,GAAGA,CAACC,cAAc,GAAG,eAAe,KAAK;EAC1E,OAAO,CAACC,MAAM,EAAEC,IAAI,KAAK;IACvB,MAAMC,OAAO,GAAGC,OAAO,CAACC,GAAG,CAACC,gBAAgB,IAAIN,cAAc;IAC9D,MAAMO,IAAI,GAAGH,OAAO,CAACC,GAAG,CAACG,uBAAuB,IAAI,gBAAgB;IAEpE,IAAIJ,OAAO,CAACC,GAAG,CAACI,QAAQ,KAAK,MAAM,EAAE;MACnCR,MAAM,CAACS,EAAE,CAAC,SAAS,EAAE,MAAM;QACzBT,MAAM,CAACU,YAAY,CACjB,QAAQ,EACR,CAAC,SAAS,EAAE,GAAGR,OAAO,IAAII,IAAI,IAAIL,IAAI,EAAE,CAAC,EACzCU,GAAG,IAAI;UACL,IAAIA,GAAG,EAAE;YACPC,OAAO,CAACC,KAAK,CAAC,iCAAiCZ,IAAI,GAAG,EAAEU,GAAG,CAAC;UAC9D,CAAC,MAAM;YACLC,OAAO,CAACE,GAAG,CAAC,8BAA8BX,OAAO,CAACY,GAAG,KAAKd,IAAI,GAAG,CAAC;UACpE;QACF,CACF,CAAC;MACH,CAAC,CAAC;IACJ;EACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,MAAMe,6BAA6B,GAAGA,CAACjB,cAAc,GAAG,eAAe,KAAK;EAC1E,OAAO,CAACC,MAAM,EAAEC,IAAI,KAAK;IACvB,MAAMC,OAAO,GAAGC,OAAO,CAACC,GAAG,CAACC,gBAAgB,IAAIN,cAAc;IAC9D,MAAMO,IAAI,GAAGH,OAAO,CAACC,GAAG,CAACG,uBAAuB,IAAI,gBAAgB;IAEpE,IAAIJ,OAAO,CAACC,GAAG,CAACI,QAAQ,KAAK,MAAM,EAAE;MACnCR,MAAM,CAACiB,IAAI,CAAC,SAAS,EAAE,MAAM;QAC3BjB,MAAM,CACHkB,IAAI,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,GAAGhB,OAAO,IAAII,IAAI,IAAIL,IAAI,EAAE,CAAC,CAAC,CACzDkB,IAAI,CAAC,MAAM;UACVP,OAAO,CAACE,GAAG,CAAC,8BAA8BX,OAAO,CAACY,GAAG,KAAKd,IAAI,GAAG,CAAC;QACpE,CAAC,CAAC,CACDmB,KAAK,CAACT,GAAG,IAAI;UACZC,OAAO,CAACC,KAAK,CAAC,iCAAiCZ,IAAI,GAAG,EAAEU,GAAG,CAAC;QAC9D,CAAC,CAAC;MACN,CAAC,CAAC;IACJ;EACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,MAAMU,6BAA6B,GAAGA,CAACtB,cAAc,GAAG,eAAe,KAAK;EAC1E,OAAO,CAACC,MAAM,EAAEC,IAAI,KAAK;IACvB,MAAMC,OAAO,GAAGC,OAAO,CAACC,GAAG,CAACC,gBAAgB,IAAIN,cAAc;IAC9D,MAAMO,IAAI,GAAGH,OAAO,CAACC,GAAG,CAACG,uBAAuB,IAAI,gBAAgB;IAEpE,IAAIJ,OAAO,CAACC,GAAG,CAACI,QAAQ,KAAK,MAAM,EAAE;MACnCR,MAAM,CAACS,EAAE,CAAC,OAAO,EAAE,YAAY;QAC7B,IAAI;UACF,MAAMT,MAAM,CAACsB,WAAW,CAAC,CACvB,QAAQ,EACR,SAAS,EACT,GAAGpB,OAAO,IAAII,IAAI,IAAIL,IAAI,EAAE,CAC7B,CAAC;UACFW,OAAO,CAACE,GAAG,CAAC,8BAA8BX,OAAO,CAACY,GAAG,KAAKd,IAAI,GAAG,CAAC;QACpE,CAAC,CAAC,OAAOU,GAAG,EAAE;UACZC,OAAO,CAACC,KAAK,CAAC,iCAAiCZ,IAAI,GAAG,EAAEU,GAAG,CAAC;QAC9D;MACF,CAAC,CAAC;IACJ;EACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,MAAMY,SAAS,GAAGvB,MAAM,IAAI;EAC1B,MAAMwB,MAAM,GACVxB,MAAM,IACN,OAAOA,MAAM,CAACsB,WAAW,KAAK,UAAU,IACxC,OAAOtB,MAAM,CAACyB,UAAU,KAAK,UAAU,IACvCzB,MAAM,CAAC0B,OAAO,KAAKC,SAAS;EAC9Bf,OAAO,CAACE,GAAG,CAAC,uCAAuC,EAAEd,MAAM,CAACsB,WAAW,CAAC;EACxEV,OAAO,CAACE,GAAG,CAAC,wDAAwD,EAAE,OAAOd,MAAM,CAACsB,WAAW,KAAK,UAAU,CAAC;EAC/GV,OAAO,CAACE,GAAG,CAAC,sCAAsC,EAAEd,MAAM,CAACyB,UAAU,CAAC;EACtEb,OAAO,CAACE,GAAG,CAAC,uDAAuD,EAAE,OAAOd,MAAM,CAACyB,UAAU,KAAK,UAAU,CAAC;EAC7Gb,OAAO,CAACE,GAAG,CAAC,mCAAmC,EAAEd,MAAM,CAAC0B,OAAO,CAAC;EAChEd,OAAO,CAACE,GAAG,CAAC,iDAAiD,EAAEd,MAAM,CAAC0B,OAAO,KAAKC,SAAS,CAAC;EAE5Ff,OAAO,CAACE,GAAG,CAAC,0BAA0B,EAAEU,MAAM,EAAE,cAAc,EAAExB,MAAM,EAAE4B,WAAW,EAAE3B,IAAI,CAAC;EAC1F,OAAOuB,MAAM;AACf,CAAC;AAEDK,MAAM,CAACC,OAAO,GAAG;EACfhC,6BAA6B;EAC7BuB,6BAA6B;EAC7BL,6BAA6B;EAC7BO;AACF,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -98,7 +98,7 @@ class QueueRedisMetricsClient extends RedisMetricsClient {
|
|
|
98
98
|
* @returns {object|any} Redis config object for BeeQueue or Redis client instance
|
|
99
99
|
*/
|
|
100
100
|
getConfigForDifferentRedis = () => {
|
|
101
|
-
if (isIORedis(this.
|
|
101
|
+
if (isIORedis(this.redisClient)) {
|
|
102
102
|
const { host, port, db, password } = this.redisClient.options
|
|
103
103
|
return { host, port, db, password }
|
|
104
104
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { MetricsClient } = require('.')
|
|
2
|
+
const { isIORedis } = require('./redisUtils')
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* RedisMetricsClient extends MetricsClient to collect
|
|
@@ -71,6 +72,17 @@ class RedisMetricsClient extends MetricsClient {
|
|
|
71
72
|
)
|
|
72
73
|
console.log('Redis client info function:', this.redisClient.info)
|
|
73
74
|
|
|
75
|
+
// node-redis ioredis
|
|
76
|
+
if (isIORedis(this.redisClient)) {
|
|
77
|
+
console.log('Detected node-redis ioredis')
|
|
78
|
+
try {
|
|
79
|
+
const result = await this.redisClient.info(section)
|
|
80
|
+
return result
|
|
81
|
+
} catch (err) {
|
|
82
|
+
throw new Error(`Failed to get Redis INFO: ${err.message}`)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
74
86
|
// node-redis v3 (uses callback)
|
|
75
87
|
if (typeof this.redisClient.send_command === 'function') {
|
|
76
88
|
console.log('Detected node-redis v3')
|
|
@@ -84,7 +96,7 @@ class RedisMetricsClient extends MetricsClient {
|
|
|
84
96
|
|
|
85
97
|
// node-redis v4 or ioredis (info returns Promise)
|
|
86
98
|
if (typeof this.redisClient.info === 'function') {
|
|
87
|
-
console.log('Detected node-redis v4
|
|
99
|
+
console.log('Detected node-redis v4')
|
|
88
100
|
try {
|
|
89
101
|
const result = await this.redisClient.info(section)
|
|
90
102
|
return result
|
package/src/redisUtils.js
CHANGED
|
@@ -85,17 +85,24 @@ const createSetClientNameForRedisV4 = (defaultAppName = 'undefined-app') => {
|
|
|
85
85
|
* Check if a Redis client is an ioredis instance
|
|
86
86
|
*
|
|
87
87
|
* @param {any} client - Redis client instance
|
|
88
|
-
* @returns {boolean} True if the client is ioredis
|
|
88
|
+
* @returns {boolean} True if the client is ioredis
|
|
89
89
|
*/
|
|
90
90
|
const isIORedis = client => {
|
|
91
|
-
|
|
91
|
+
const result =
|
|
92
92
|
client &&
|
|
93
|
-
typeof client.
|
|
93
|
+
typeof client.sendCommand === 'function' &&
|
|
94
94
|
typeof client.disconnect === 'function' &&
|
|
95
|
-
client.
|
|
96
|
-
|
|
97
|
-
)
|
|
98
|
-
|
|
95
|
+
client.options !== undefined;
|
|
96
|
+
console.log('[debug] isIORedis client.sendCommand:', client.sendCommand);
|
|
97
|
+
console.log('[debug] isIORedis client.sendCommand === \'function\':', typeof client.sendCommand === 'function');
|
|
98
|
+
console.log('[debug] isIORedis client.disconnect:', client.disconnect);
|
|
99
|
+
console.log('[debug] isIORedis client.disconnect === \'function\':', typeof client.disconnect === 'function');
|
|
100
|
+
console.log('[debug] isIORedis client.options:', client.options);
|
|
101
|
+
console.log('[debug] isIORedis client.options !== undefined:', client.options !== undefined);
|
|
102
|
+
|
|
103
|
+
console.log('[debug] isIORedis check:', result, 'constructor:', client?.constructor?.name);
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
99
106
|
|
|
100
107
|
module.exports = {
|
|
101
108
|
createSetClientNameForRedisV3,
|