@adalo/metrics 0.1.81 → 0.1.82

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.
@@ -40,10 +40,10 @@ export class DatabaseMetricsClient extends MetricsClient {
40
40
  /** Gauge for Database connections */
41
41
  databaseConnectionsGauge: import("prom-client").Gauge<string>;
42
42
  /**
43
- * @param {any} pool - PG connection pool
43
+ * @param {Pool} pool - PG connection pool
44
44
  * @returns {Promise<{ current: number, max: number, dbName: string }>}
45
45
  */
46
- getDBConnectionsAndName: (pool: any) => Promise<{
46
+ getDBConnectionsAndName: (pool: Pool) => Promise<{
47
47
  current: number;
48
48
  max: number;
49
49
  dbName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"metricsDatabaseClient.d.ts","sourceRoot":"","sources":["../src/metricsDatabaseClient.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH;IACE;;;;;;;;;;;;;;;OAeG;IACH;QAd2B,WAAW,EAA3B,MAAM;QACa,wBAAwB;QAC1B,OAAO;QACP,MAAM;QACN,WAAW;QACV,OAAO;QACP,SAAS;QACV,cAAc;QACd,iBAAiB;QACjB,WAAW;QACV,gBAAgB;QAChB,mBAAmB;QAClB,iBAAiB;OA0E9C;IAlBC,sBAAuB;IAUvB,qCAAqC;IACrC,8DAIE;IAKJ;;;OAGG;IACH,gCAHW,GAAG,KACD,QAAQ;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CA4BrE;IAED;;;OAGG;IACH,8BAFa,QAAQ,IAAI,CAAC,CAqBzB;IAED;;;OAGG;IACH,2BAFa,QAAQ,IAAI,CAAC,CAoBzB;IAED;;;OAGG;IACH,sDAMC;CAwBF"}
1
+ {"version":3,"file":"metricsDatabaseClient.d.ts","sourceRoot":"","sources":["../src/metricsDatabaseClient.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH;IACE;;;;;;;;;;;;;;;OAeG;IACH;QAd2B,WAAW,EAA3B,MAAM;QACa,wBAAwB;QAC1B,OAAO;QACP,MAAM;QACN,WAAW;QACV,OAAO;QACP,SAAS;QACV,cAAc;QACd,iBAAiB;QACjB,WAAW;QACV,gBAAgB;QAChB,mBAAmB;QAClB,iBAAiB;OA0E9C;IAlBC,sBAAuB;IAUvB,qCAAqC;IACrC,8DAIE;IAKJ;;;OAGG;IACH,gCAHW,IAAI,KACF,QAAQ;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CA4BrE;IAED;;;OAGG;IACH,8BAFa,QAAQ,IAAI,CAAC,CAqBzB;IAED;;;OAGG;IACH,2BAFa,QAAQ,IAAI,CAAC,CAoBzB;IAED;;;OAGG;IACH,sDAMC;CAwBF"}
@@ -97,7 +97,7 @@ class DatabaseMetricsClient extends MetricsClient {
97
97
  }
98
98
 
99
99
  /**
100
- * @param {any} pool - PG connection pool
100
+ * @param {Pool} pool - PG connection pool
101
101
  * @returns {Promise<{ current: number, max: number, dbName: string }>}
102
102
  */
103
103
  getDBConnectionsAndName = async pool => {
@@ -110,9 +110,9 @@ class DatabaseMetricsClient extends MetricsClient {
110
110
  if (!dbName && pool.options?.connectionString) {
111
111
  try {
112
112
  const url = new URL(pool.options.connectionString);
113
- dbName = url.pathname.replace(/^\//, ''); // remove leading /
113
+ dbName = url.pathname.replace(/^\//, '');
114
114
  } catch {
115
- dbName = pool.options.connectionString; // fallback
115
+ dbName = pool.options.connectionString;
116
116
  }
117
117
  }
118
118
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"metricsDatabaseClient.js","names":["Pool","require","MetricsClient","DatabaseMetricsClient","constructor","databaseUrl","additional_database_urls","metricsConfig","intervalSec","parseInt","process","env","METRICS_DATABASE_INTERVAL_SEC","startupValidation","console","error","mainPool","connectionString","query","end","info","err","message","url","p","scripDefaultMetrics","processType","databasePools","push","databaseConnectionsGauge","createGauge","name","help","labelNames","withDefaultLabels","_setCleanupHandlers","getDBConnectionsAndName","pool","currentRes","current","rows","maxRes","max","dbName","options","database","URL","pathname","replace","collectDatabaseMetrics","set","getDefaultLabels","database_name","max_connections","String","warn","pushDatabaseMetrics","gatewayPush","metricsLogValues","metricObjects","registry","getMetricsAsJSON","JSON","stringify","startPush","_startPush","catch","cleanup","exit","on","module","exports"],"sources":["../src/metricsDatabaseClient.js"],"sourcesContent":["const { Pool } = require('pg')\nconst { MetricsClient } = require('.')\n\n/**\n * DatabaseMetricsClient collects Postgres connection metrics\n * and pushes them to Prometheus Pushgateway.\n *\n * @extends MetricsClient\n */\nclass DatabaseMetricsClient extends MetricsClient {\n /**\n * @param {Object} options\n * @param {string} options.databaseUrl - Required main database URL\n * @param {string[]} [options.additional_database_urls] - Optional additional DB URLs\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\n * @param {boolean} [options.removeOldMetrics] - Remove old metrics by service\n * @param {boolean} [options.scripDefaultMetrics] - Skip default metrics creation\n * @param {function} [options.startupValidation] - Function to validate startup\n */\n constructor({\n databaseUrl,\n additional_database_urls = [],\n ...metricsConfig\n } = {}) {\n const intervalSec =\n metricsConfig.intervalSec ||\n parseInt(process.env.METRICS_DATABASE_INTERVAL_SEC || '', 10) ||\n 60\n\n const startupValidation = async () => {\n if (!databaseUrl) {\n console.error(`[database-metrics] ❌ METRICS_DATABASE_URL is required`)\n return false\n }\n\n try {\n const mainPool = new Pool({ connectionString: databaseUrl })\n await mainPool.query('SELECT 1')\n await mainPool.end()\n console.info(`[database-metrics] ✓ Main database OK`)\n } catch (err) {\n console.error(\n `[database-metrics] ❌ Cannot connect to main database: ${err.message}`\n )\n return false\n }\n\n for (const url of additional_database_urls) {\n try {\n const p = new Pool({ connectionString: url })\n await p.query('SELECT 1')\n await p.end()\n console.info(`[database-metrics] ✓ Additional database OK: ${url}`)\n } catch (err) {\n console.error(\n `[database-metrics] ⚠ Skipping additional database: ${url}`\n )\n console.error(`[database-metrics] ${err.message}`)\n }\n }\n\n console.info(`[database-metrics] Database metrics collection starting`)\n return true\n }\n\n super({\n ...metricsConfig,\n scripDefaultMetrics: true,\n processType: metricsConfig.processType || 'database-metrics',\n intervalSec,\n startupValidation,\n })\n\n this.databasePools = []\n\n if (databaseUrl) {\n this.databasePools.push(new Pool({ connectionString: databaseUrl }))\n }\n\n for (const url of additional_database_urls) {\n this.databasePools.push(new Pool({ connectionString: url }))\n }\n\n /** Gauge for Database connections */\n this.databaseConnectionsGauge = this.createGauge({\n name: 'app_database_connections',\n help: 'Postgres database connections',\n labelNames: this.withDefaultLabels(['max_connections', 'database_name']),\n })\n\n this._setCleanupHandlers()\n }\n\n /**\n * @param {any} pool - PG connection pool\n * @returns {Promise<{ current: number, max: number, dbName: string }>}\n */\n getDBConnectionsAndName = async pool => {\n try {\n const currentRes = await pool.query(\n 'SELECT COUNT(*) AS current FROM pg_stat_activity WHERE datname = current_database()'\n )\n const current = parseInt(currentRes.rows[0]?.current || 0, 10)\n\n const maxRes = await pool.query(\n \"SELECT current_setting('max_connections') AS max\"\n )\n const max = parseInt(maxRes.rows[0]?.max || 0, 10)\n\n let dbName = pool.options?.database\n if (!dbName && pool.options?.connectionString) {\n try {\n const url = new URL(pool.options.connectionString)\n dbName = url.pathname.replace(/^\\//, '') // remove leading /\n } catch {\n dbName = pool.options.connectionString // fallback\n }\n }\n\n return { current, max, dbName }\n } catch (err) {\n return { current: 0, max: 0, dbName: pool.options?.database || '' }\n }\n }\n\n /**\n * Collect database connection metrics for all configured pools\n * @returns {Promise<void>}\n */\n collectDatabaseMetrics = async () => {\n for (const pool of this.databasePools) {\n try {\n const { current, max, dbName } = await this.getDBConnectionsAndName(\n pool\n )\n\n this.databaseConnectionsGauge.set(\n {\n ...this.getDefaultLabels(),\n database_name: dbName,\n max_connections: String(max),\n },\n current\n )\n } catch (err) {\n console.warn(`[database-metrics] Failed to collect: ${err.message}`)\n }\n }\n }\n\n /**\n * Push database metrics to Prometheus Pushgateway\n * @returns {Promise<void>}\n */\n pushDatabaseMetrics = async () => {\n try {\n await this.collectDatabaseMetrics()\n await this.gatewayPush()\n\n if (this.metricsLogValues) {\n const metricObjects = await this.registry.getMetricsAsJSON()\n console.info(\n `[database-metrics] Collected DB metrics`,\n JSON.stringify(metricObjects, null, 2)\n )\n }\n } catch (error) {\n console.error(\n `[database-metrics] Failed to collect DB 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.pushDatabaseMetrics().catch(err => {\n console.error(`[database-metrics] Failed to push DB metrics:`, err)\n })\n })\n }\n\n /**\n * Cleanup database pools and exit process\n * @returns {Promise<void>}\n */\n cleanup = async () => {\n try {\n if (this.databasePools) {\n for (const pool of this.databasePools) {\n await pool.end()\n }\n }\n } catch (err) {\n console.error('[database-metrics] Error during cleanup:', err)\n }\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 = { DatabaseMetricsClient }\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"metricsDatabaseClient.js","names":["Pool","require","MetricsClient","DatabaseMetricsClient","constructor","databaseUrl","additional_database_urls","metricsConfig","intervalSec","parseInt","process","env","METRICS_DATABASE_INTERVAL_SEC","startupValidation","console","error","mainPool","connectionString","query","end","info","err","message","url","p","scripDefaultMetrics","processType","databasePools","push","databaseConnectionsGauge","createGauge","name","help","labelNames","withDefaultLabels","_setCleanupHandlers","getDBConnectionsAndName","pool","currentRes","current","rows","maxRes","max","dbName","options","database","URL","pathname","replace","collectDatabaseMetrics","set","getDefaultLabels","database_name","max_connections","String","warn","pushDatabaseMetrics","gatewayPush","metricsLogValues","metricObjects","registry","getMetricsAsJSON","JSON","stringify","startPush","_startPush","catch","cleanup","exit","on","module","exports"],"sources":["../src/metricsDatabaseClient.js"],"sourcesContent":["const { Pool } = require('pg')\nconst { MetricsClient } = require('.')\n\n/**\n * DatabaseMetricsClient collects Postgres connection metrics\n * and pushes them to Prometheus Pushgateway.\n *\n * @extends MetricsClient\n */\nclass DatabaseMetricsClient extends MetricsClient {\n /**\n * @param {Object} options\n * @param {string} options.databaseUrl - Required main database URL\n * @param {string[]} [options.additional_database_urls] - Optional additional DB URLs\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\n * @param {boolean} [options.removeOldMetrics] - Remove old metrics by service\n * @param {boolean} [options.scripDefaultMetrics] - Skip default metrics creation\n * @param {function} [options.startupValidation] - Function to validate startup\n */\n constructor({\n databaseUrl,\n additional_database_urls = [],\n ...metricsConfig\n } = {}) {\n const intervalSec =\n metricsConfig.intervalSec ||\n parseInt(process.env.METRICS_DATABASE_INTERVAL_SEC || '', 10) ||\n 60\n\n const startupValidation = async () => {\n if (!databaseUrl) {\n console.error(`[database-metrics] ❌ METRICS_DATABASE_URL is required`)\n return false\n }\n\n try {\n const mainPool = new Pool({ connectionString: databaseUrl })\n await mainPool.query('SELECT 1')\n await mainPool.end()\n console.info(`[database-metrics] ✓ Main database OK`)\n } catch (err) {\n console.error(\n `[database-metrics] ❌ Cannot connect to main database: ${err.message}`\n )\n return false\n }\n\n for (const url of additional_database_urls) {\n try {\n const p = new Pool({ connectionString: url })\n await p.query('SELECT 1')\n await p.end()\n console.info(`[database-metrics] ✓ Additional database OK: ${url}`)\n } catch (err) {\n console.error(\n `[database-metrics] ⚠ Skipping additional database: ${url}`\n )\n console.error(`[database-metrics] ${err.message}`)\n }\n }\n\n console.info(`[database-metrics] Database metrics collection starting`)\n return true\n }\n\n super({\n ...metricsConfig,\n scripDefaultMetrics: true,\n processType: metricsConfig.processType || 'database-metrics',\n intervalSec,\n startupValidation,\n })\n\n this.databasePools = []\n\n if (databaseUrl) {\n this.databasePools.push(new Pool({ connectionString: databaseUrl }))\n }\n\n for (const url of additional_database_urls) {\n this.databasePools.push(new Pool({ connectionString: url }))\n }\n\n /** Gauge for Database connections */\n this.databaseConnectionsGauge = this.createGauge({\n name: 'app_database_connections',\n help: 'Postgres database connections',\n labelNames: this.withDefaultLabels(['max_connections', 'database_name']),\n })\n\n this._setCleanupHandlers()\n }\n\n /**\n * @param {Pool} pool - PG connection pool\n * @returns {Promise<{ current: number, max: number, dbName: string }>}\n */\n getDBConnectionsAndName = async pool => {\n try {\n const currentRes = await pool.query(\n 'SELECT COUNT(*) AS current FROM pg_stat_activity WHERE datname = current_database()'\n )\n const current = parseInt(currentRes.rows[0]?.current || 0, 10)\n\n const maxRes = await pool.query(\n \"SELECT current_setting('max_connections') AS max\"\n )\n const max = parseInt(maxRes.rows[0]?.max || 0, 10)\n\n let dbName = pool.options?.database\n if (!dbName && pool.options?.connectionString) {\n try {\n const url = new URL(pool.options.connectionString)\n dbName = url.pathname.replace(/^\\//, '')\n } catch {\n dbName = pool.options.connectionString\n }\n }\n\n return { current, max, dbName }\n } catch (err) {\n return { current: 0, max: 0, dbName: pool.options?.database || '' }\n }\n }\n\n /**\n * Collect database connection metrics for all configured pools\n * @returns {Promise<void>}\n */\n collectDatabaseMetrics = async () => {\n for (const pool of this.databasePools) {\n try {\n const { current, max, dbName } = await this.getDBConnectionsAndName(\n pool\n )\n\n this.databaseConnectionsGauge.set(\n {\n ...this.getDefaultLabels(),\n database_name: dbName,\n max_connections: String(max),\n },\n current\n )\n } catch (err) {\n console.warn(`[database-metrics] Failed to collect: ${err.message}`)\n }\n }\n }\n\n /**\n * Push database metrics to Prometheus Pushgateway\n * @returns {Promise<void>}\n */\n pushDatabaseMetrics = async () => {\n try {\n await this.collectDatabaseMetrics()\n await this.gatewayPush()\n\n if (this.metricsLogValues) {\n const metricObjects = await this.registry.getMetricsAsJSON()\n console.info(\n `[database-metrics] Collected DB metrics`,\n JSON.stringify(metricObjects, null, 2)\n )\n }\n } catch (error) {\n console.error(\n `[database-metrics] Failed to collect DB 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.pushDatabaseMetrics().catch(err => {\n console.error(`[database-metrics] Failed to push DB metrics:`, err)\n })\n })\n }\n\n /**\n * Cleanup database pools and exit process\n * @returns {Promise<void>}\n */\n cleanup = async () => {\n try {\n if (this.databasePools) {\n for (const pool of this.databasePools) {\n await pool.end()\n }\n }\n } catch (err) {\n console.error('[database-metrics] Error during cleanup:', err)\n }\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 = { DatabaseMetricsClient }\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adalo/metrics",
3
- "version": "0.1.81",
3
+ "version": "0.1.82",
4
4
  "description": "Reusable metrics utilities for Node.js and Laravel apps",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -99,7 +99,7 @@ class DatabaseMetricsClient extends MetricsClient {
99
99
  }
100
100
 
101
101
  /**
102
- * @param {any} pool - PG connection pool
102
+ * @param {Pool} pool - PG connection pool
103
103
  * @returns {Promise<{ current: number, max: number, dbName: string }>}
104
104
  */
105
105
  getDBConnectionsAndName = async pool => {
@@ -118,9 +118,9 @@ class DatabaseMetricsClient extends MetricsClient {
118
118
  if (!dbName && pool.options?.connectionString) {
119
119
  try {
120
120
  const url = new URL(pool.options.connectionString)
121
- dbName = url.pathname.replace(/^\//, '') // remove leading /
121
+ dbName = url.pathname.replace(/^\//, '')
122
122
  } catch {
123
- dbName = pool.options.connectionString // fallback
123
+ dbName = pool.options.connectionString
124
124
  }
125
125
  }
126
126