@adalo/metrics 0.1.3 → 0.1.5

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.
@@ -49,8 +49,6 @@ export class MetricsClient {
49
49
  gaugeUpdaters: {
50
50
  [x: string]: () => number | Promise<number>;
51
51
  };
52
- /** @type {Object<string, function(data?: object, value?: number): void>} */
53
- counterUpdaters: any;
54
52
  _lastUsageMicros: number;
55
53
  _lastCheckTime: number;
56
54
  /**
@@ -116,6 +114,7 @@ export class MetricsClient {
116
114
  */
117
115
  startPush: (interval?: number | undefined) => void;
118
116
  cleanup: () => Promise<never>;
117
+ _clearOldWorkers: () => Promise<void>;
119
118
  _setCleanupHandlers: () => void;
120
119
  }
121
120
  import client = require("prom-client");
@@ -1 +1 @@
1
- {"version":3,"file":"metricsClient.d.ts","sourceRoot":"","sources":["../src/metricsClient.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH;IACE;;;;;;;;;;;OAWG;IACH;QAV2B,OAAO;QACP,MAAM;QACN,WAAW;QACV,OAAO;QACP,SAAS;QACV,cAAc;QACd,eAAe;QACf,mBAAmB;QACnB,WAAW;OA8DrC;IA3DC,gBACiE;IACjE,eAAqE;IACrE,oBAG6B;IAC7B,iBAAuE;IACvE,mBAC+D;IAC/D,uBACoE;IACpE,wBACsE;IACtE,4BAGI;IACJ,oBAGI;IAEJ,mBAAyF;IAEzF,sEAAqC;IAGrC;;;;MAIC;IAKD,wEAOC;IAED,WAAgB;IAChB,aAAkB;IAElB,mEAAmE;IACnE;YADkB,MAAM,SAAc,MAAM,GAAG,QAAQ,MAAM,CAAC;MACvC;IACvB,4EAA4E;IAC5E,qBAAyB;IAEzB,yBAAyB;IACzB,uBAAgC;IAMlC;;;OAGG;IACH,4BA8CC;IAED;;;;;;;OAOG;IACH,oBANW,MAAM,QACN,MAAM,oBACM,MAAM,GAAC,QAAQ,MAAM,CAAC,qDAEhC,OAAO,KAAK,CAqBxB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,QACN,MAAM,gEAEY,MAAM,4BAAU,MAAM,KAAG,IAAI,CAmBzD;IAED;;;OAGG;IACH,0BAFa,MAAM,CA2BlB;IAED;;;OAGG;IACH,oBAFa,MAAM,CAiBlB;IAED;;;OAGG;IACH,2BAFa,MAAM,CAWlB;IAED;;;OAGG;IACH,2BAFa,MAAM,CAgBlB;IAED;;;OAGG;IACH,cAFa,QAAQ,MAAM,CAAC,CAO3B;IAED;;;OAGG;IACH,oEA0BC;IAED;;OAEG;IACH,iCAgCC;IAED;;;OAGG;IACH,mDAYC;IAED,8BAWC;IAGD,gCAGC;CACF"}
1
+ {"version":3,"file":"metricsClient.d.ts","sourceRoot":"","sources":["../src/metricsClient.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH;IACE;;;;;;;;;;;OAWG;IACH;QAV2B,OAAO;QACP,MAAM;QACN,WAAW;QACV,OAAO;QACP,SAAS;QACV,cAAc;QACd,eAAe;QACf,mBAAmB;QACnB,WAAW;OA4DrC;IAzDC,gBACiE;IACjE,eAAqE;IACrE,oBAG6B;IAC7B,iBAAuE;IACvE,mBAC+D;IAC/D,uBACoE;IACpE,wBACsE;IACtE,4BAGI;IACJ,oBAGI;IAEJ,mBAAyF;IAEzF,sEAAqC;IAGrC;;;;MAIC;IAKD,wEAOC;IAED,WAAgB;IAChB,aAAkB;IAElB,mEAAmE;IACnE;YADkB,MAAM,SAAc,MAAM,GAAG,QAAQ,MAAM,CAAC;MACvC;IACvB,yBAAyB;IACzB,uBAAgC;IAOlC;;;OAGG;IACH,4BA8CC;IAED;;;;;;;OAOG;IACH,oBANW,MAAM,QACN,MAAM,oBACM,MAAM,GAAC,QAAQ,MAAM,CAAC,qDAEhC,OAAO,KAAK,CAqBxB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,QACN,MAAM,gEAEY,MAAM,4BAAU,MAAM,KAAG,IAAI,CAmBzD;IAED;;;OAGG;IACH,0BAFa,MAAM,CA2BlB;IAED;;;OAGG;IACH,oBAFa,MAAM,CAiBlB;IAED;;;OAGG;IACH,2BAFa,MAAM,CAWlB;IAED;;;OAGG;IACH,2BAFa,MAAM,CAgBlB;IAED;;;OAGG;IACH,cAFa,QAAQ,MAAM,CAAC,CAO3B;IAED;;;OAGG;IACH,oEA0BC;IAED;;OAEG;IACH,iCAgCC;IAED;;;OAGG;IACH,mDAYC;IAED,8BAWC;IAED,sCASC;IAED,gCAGC;CACF"}
@@ -56,12 +56,12 @@ class MetricsClient {
56
56
 
57
57
  /** @type {Object<string, function(): number | Promise<number>>} */
58
58
  this.gaugeUpdaters = {};
59
- /** @type {Object<string, function(data?: object, value?: number): void>} */
60
- this.counterUpdaters = {};
61
59
  this._lastUsageMicros = 0;
62
60
  this._lastCheckTime = Date.now();
63
- this._initDefaultMetrics();
64
- this._setCleanupHandlers();
61
+ this._clearOldWorkers().then(_ => {
62
+ this._initDefaultMetrics();
63
+ this._setCleanupHandlers();
64
+ });
65
65
  }
66
66
 
67
67
  /**
@@ -294,6 +294,16 @@ class MetricsClient {
294
294
  }
295
295
  process.exit(0);
296
296
  };
297
+ _clearOldWorkers = async () => {
298
+ try {
299
+ await this.gateway.delete({
300
+ jobName: this.appName
301
+ });
302
+ console.warn(`${this.prefixLogs} Cleared all old workers metrics.`);
303
+ } catch (err) {
304
+ console.error(`${this.prefixLogs} Failed to clear old metrics:`, err);
305
+ }
306
+ };
297
307
  _setCleanupHandlers = () => {
298
308
  process.on('SIGINT', this.cleanup);
299
309
  process.on('SIGTERM', this.cleanup);
@@ -1 +1 @@
1
- {"version":3,"file":"metricsClient.js","names":["client","require","fs","os","https","MetricsClient","constructor","config","appName","process","env","METRICS_APP_NAME","dynoId","HOSTNAME","processType","BUILD_DYNO_PROCESS_TYPE","enabled","METRICS_ENABLED","logValues","METRICS_LOG_VALUES","pushgatewayUrl","METRICS_PUSHGATEWAY_URL","pushgatewayUser","METRICS_PUSHGATEWAY_USER","pushgatewayPassword","METRICS_PUSHGATEWAY_PASSWORD","intervalSec","parseInt","METRICS_INTERVAL_SEC","prefixLogs","registry","Registry","collectDefaultMetrics","register","defaultLabels","app","dyno_id","process_type","authToken","Buffer","from","toString","gateway","Pushgateway","headers","Authorization","agent","Agent","keepAlive","gauges","counters","gaugeUpdaters","counterUpdaters","_lastUsageMicros","_lastCheckTime","Date","now","_initDefaultMetrics","_setCleanupHandlers","createGauge","getCpuUsagePercent","getAvailableCPUs","getContainerMemoryUsage","measureLag","getContainerMemoryLimit","uptime","createCounter","Object","keys","name","help","updateFn","labelNames","g","Gauge","registers","triggerFn","c","Counter","data","value","inc","stat","readFileSync","match","currentUsage","deltaUsage","deltaTime","cpuMaxPath","existsSync","quotaStr","periodStr","trim","split","cpus","length","memoryUsage","rss","path","val","parsed","totalmem","Promise","resolve","start","setImmediate","countHttpRequestMiddleware","req","res","next","on","route","appId","params","body","query","databaseId","app_http_requests_total","method","status_code","statusCode","duration","requestSize","pushMetrics","entries","result","undefined","set","err","console","error","push","jobName","groupings","instance","values","forEach","counter","reset","metrics","getMetricsAsJSON","log","JSON","stringify","startPush","interval","warn","setInterval","catch","cleanup","delete","exit","module","exports"],"sources":["../src/metricsClient.js"],"sourcesContent":["const client = require('prom-client')\nconst fs = require('fs')\nconst os = require('os')\nconst https = require('https')\n\n/**\n * MetricsClient handles Prometheus metrics collection and push.\n * Supports gauges, counters, default metrics, and custom metrics.\n */\nclass MetricsClient {\n /**\n * @param {Object} config\n * @param {string} [config.appName] Name of the application\n * @param {string} [config.dynoId] Dyno/instance ID\n * @param {string} [config.processType] Process type (web, worker, etc.)\n * @param {boolean} [config.enabled] Enable metrics collection\n * @param {boolean} [config.logValues] Log metrics values to console\n * @param {string} [config.pushgatewayUrl] PushGateway URL\n * @param {string} [config.pushgatewayUser] PushGateway username\n * @param {string} [config.pushgatewayPassword] PushGateway password\n * @param {number} [config.intervalSec] Interval in seconds for pushing metrics\n */\n constructor(config = {}) {\n this.appName =\n config.appName || process.env.METRICS_APP_NAME || 'unknown-app'\n this.dynoId = config.dynoId || process.env.HOSTNAME || 'unknown-dyno'\n this.processType =\n config.processType ||\n process.env.BUILD_DYNO_PROCESS_TYPE ||\n 'undefined_build_dyno_type'\n this.enabled = config.enabled ?? process.env.METRICS_ENABLED === 'true'\n this.logValues =\n config.logValues ?? process.env.METRICS_LOG_VALUES === 'true'\n this.pushgatewayUrl =\n config.pushgatewayUrl || process.env.METRICS_PUSHGATEWAY_URL || ''\n this.pushgatewayUser =\n config.pushgatewayUser || process.env.METRICS_PUSHGATEWAY_USER || ''\n this.pushgatewayPassword =\n config.pushgatewayPassword ||\n process.env.METRICS_PUSHGATEWAY_PASSWORD ||\n ''\n this.intervalSec =\n config.intervalSec ||\n parseInt(process.env.METRICS_INTERVAL_SEC || '', 10) ||\n 15\n\n this.prefixLogs = `[${this.processType}] [${this.appName}] [${this.dynoId}] [Monitoring]`\n\n this.registry = new client.Registry()\n client.collectDefaultMetrics({ register: this.registry })\n\n this.defaultLabels = {\n app: this.appName,\n dyno_id: this.dynoId,\n process_type: this.processType,\n }\n\n const authToken = Buffer.from(\n `${this.pushgatewayUser}:${this.pushgatewayPassword}`\n ).toString('base64')\n this.gateway = new client.Pushgateway(\n this.pushgatewayUrl,\n {\n headers: { Authorization: `Basic ${authToken}` },\n agent: new https.Agent({ keepAlive: true }),\n },\n this.registry\n )\n\n this.gauges = {}\n this.counters = {}\n\n /** @type {Object<string, function(): number | Promise<number>>} */\n this.gaugeUpdaters = {}\n /** @type {Object<string, function(data?: object, value?: number): void>} */\n this.counterUpdaters = {}\n\n this._lastUsageMicros = 0\n this._lastCheckTime = Date.now()\n\n this._initDefaultMetrics()\n this._setCleanupHandlers()\n }\n\n /**\n * Register default gauges and counters.\n * @private\n */\n _initDefaultMetrics = () => {\n this.createGauge(\n 'app_process_cpu_usage_percent',\n 'Current CPU usage of the Node.js process in percent',\n this.getCpuUsagePercent\n )\n this.createGauge(\n 'app_available_cpu_count',\n 'How many CPU cores are available to this process',\n this.getAvailableCPUs\n )\n this.createGauge(\n 'app_container_memory_usage_bytes',\n 'Current container RAM usage from cgroup',\n this.getContainerMemoryUsage\n )\n this.createGauge(\n 'app_event_loop_lag_ms',\n 'Estimated event loop lag in milliseconds',\n this.measureLag\n )\n this.createGauge(\n 'app_container_memory_limit_bytes',\n 'Max RAM available to container from cgroup (memory.max)',\n this.getContainerMemoryLimit\n )\n this.createGauge(\n 'app_uptime_seconds',\n 'How long the process has been running',\n process.uptime\n )\n\n this.createCounter(\n 'app_http_requests_total',\n 'Total number of HTTP requests handled by this process',\n [\n ...Object.keys(this.defaultLabels),\n 'method',\n 'route',\n 'appId',\n 'databaseId',\n 'duration',\n 'requestSize',\n 'status_code',\n ]\n )\n }\n\n /**\n * Create a gauge metric.\n * @param {string} name\n * @param {string} help\n * @param {function(): number|Promise<number>} [updateFn] Optional function returning value\n * @param {string[]} [labelNames]\n * @returns {client.Gauge}\n */\n createGauge = (\n name,\n help,\n updateFn,\n labelNames = Object.keys(this.defaultLabels)\n ) => {\n if (this.gauges[name]) return this.gauges[name]\n\n const g = new client.Gauge({\n name,\n help,\n labelNames,\n registers: [this.registry],\n })\n this.gauges[name] = g\n\n if (typeof updateFn === 'function') this.gaugeUpdaters[name] = updateFn\n\n return g\n }\n\n /**\n * Create a counter metric.\n * Returns a trigger function to increment the counter manually.\n * @param {string} name\n * @param {string} help\n * @param {string[]} [labelNames]\n * @returns {function(data?: object, value?: number): void} triggerFn\n */\n createCounter(name, help, labelNames = Object.keys(this.defaultLabels)) {\n if (this.counters[name]) return this.counters[name].triggerFn\n\n const c = new client.Counter({\n name,\n help,\n labelNames,\n registers: [this.registry],\n })\n this.counters[name] = c\n\n const triggerFn = (data = {}, value = 1) => {\n c.inc({ ...this.defaultLabels, ...data }, value)\n }\n\n this.counters[name].triggerFn = triggerFn\n return triggerFn\n }\n\n /**\n * Get CPU usage percent (cgroup-aware)\n * @returns {number}\n */\n getCpuUsagePercent = () => {\n try {\n const stat = fs.readFileSync('/sys/fs/cgroup/cpu.stat', 'utf-8')\n const match = stat.match(/usage_usec (\\d+)/)\n if (!match) return 0\n\n const now = Date.now()\n const currentUsage = parseInt(match[1], 10)\n\n if (this._lastUsageMicros === 0) {\n this._lastUsageMicros = currentUsage\n this._lastCheckTime = now\n return 0\n }\n\n const deltaUsage = currentUsage - this._lastUsageMicros\n const deltaTime = now - this._lastCheckTime\n\n this._lastUsageMicros = currentUsage\n this._lastCheckTime = now\n\n return (deltaUsage / (deltaTime * 1000)) * 100\n } catch {\n return 0\n }\n }\n\n /**\n * Get available CPU cores.\n * @returns {number}\n */\n getAvailableCPUs() {\n try {\n const cpuMaxPath = '/sys/fs/cgroup/cpu.max'\n if (fs.existsSync(cpuMaxPath)) {\n const [quotaStr, periodStr] = fs\n .readFileSync(cpuMaxPath, 'utf8')\n .trim()\n .split(' ')\n if (quotaStr === 'max') return os.cpus().length\n return parseInt(quotaStr, 10) / parseInt(periodStr, 10)\n }\n return os.cpus().length\n } catch {\n return 1\n }\n }\n\n /**\n * Get container memory usage in bytes.\n * @returns {number}\n */\n getContainerMemoryUsage() {\n try {\n return parseInt(\n fs.readFileSync('/sys/fs/cgroup/memory.current', 'utf-8').trim(),\n 10\n )\n } catch {\n return process.memoryUsage().rss\n }\n }\n\n /**\n * Get container memory limit in bytes.\n * @returns {number}\n */\n getContainerMemoryLimit() {\n try {\n const path = '/sys/fs/cgroup/memory.max'\n if (fs.existsSync(path)) {\n const val = fs.readFileSync(path, 'utf-8').trim()\n if (val !== 'max') {\n const parsed = parseInt(val, 10)\n if (parsed && parsed < os.totalmem()) return parsed\n }\n }\n return os.totalmem()\n } catch {\n return os.totalmem()\n }\n }\n\n /**\n * Measure event loop lag in ms.\n * @returns {Promise<number>}\n */\n measureLag() {\n return new Promise(resolve => {\n const start = Date.now()\n setImmediate(() => resolve(Date.now() - start))\n })\n }\n\n /**\n * Express middleware to count HTTP requests.\n * Increments the `app_http_requests_total` counter.\n */\n countHttpRequestMiddleware = (req, res, next) => {\n const start = Date.now()\n res.on('finish', () => {\n const route = req.route?.path || req.path || 'unknown'\n const appId =\n req.params?.appId || req.body?.appId || req.query?.appId || ''\n const databaseId =\n req.params?.databaseId ||\n req.body?.databaseId ||\n req.query?.databaseId ||\n ''\n\n this.counters?.app_http_requests_total?.triggerFn({\n method: req.method,\n route,\n status_code: res.statusCode,\n appId,\n databaseId,\n duration: Date.now() - start,\n requestSize: req.headers['content-length']\n ? parseInt(req.headers['content-length'], 10)\n : 0,\n })\n })\n\n next()\n }\n\n /**\n * Push all gauges and counters to PushGateway and optionally log.\n */\n pushMetrics = async () => {\n try {\n for (const [name, updateFn] of Object.entries(this.gaugeUpdaters)) {\n try {\n const result = updateFn()\n const val = result instanceof Promise ? await result : result\n if (val !== undefined) this.gauges[name].set(this.defaultLabels, val)\n } catch (err) {\n console.error(\n `${this.prefixLogs} Failed to update gauge ${name}:`,\n err\n )\n }\n }\n\n await this.gateway.push({\n jobName: this.appName,\n groupings: { process_type: this.processType, instance: this.dynoId },\n })\n\n Object.values(this.counters).forEach(counter => counter.reset())\n\n if (this.logValues) {\n const metrics = await this.registry.getMetricsAsJSON()\n console.log(\n `${this.prefixLogs} Metrics:\\n`,\n JSON.stringify(metrics, null, 2)\n )\n }\n } catch (err) {\n console.error(`${this.prefixLogs} Failed to push metrics:`, err)\n }\n }\n\n /**\n * Start automatic periodic push of metrics.\n * @param {number} [interval] Interval in seconds\n */\n startPush = (interval = this.intervalSec) => {\n if (!this.enabled) {\n console.warn(`${this.prefixLogs} Metrics disabled`)\n }\n\n setInterval(() => {\n this.pushMetrics().catch(err => {\n console.error(`${this.prefixLogs} Failed to push metrics:`, err)\n })\n }, interval * 1000)\n\n console.warn(`${this.prefixLogs} Metrics collection started.`)\n }\n\n cleanup = async () => {\n if (this.enabled) {\n await this.gateway.delete({\n jobName: this.appName,\n groupings: {\n process_type: this.processType,\n instance: this.dynoId,\n },\n })\n }\n process.exit(0)\n }\n\n\n _setCleanupHandlers = () => {\n process.on('SIGINT', this.cleanup)\n process.on('SIGTERM', this.cleanup)\n }\n}\n\nmodule.exports = { MetricsClient }\n"],"mappings":";;AAAA,MAAMA,MAAM,GAAGC,OAAO,CAAC,aAAa,CAAC;AACrC,MAAMC,EAAE,GAAGD,OAAO,CAAC,IAAI,CAAC;AACxB,MAAME,EAAE,GAAGF,OAAO,CAAC,IAAI,CAAC;AACxB,MAAMG,KAAK,GAAGH,OAAO,CAAC,OAAO,CAAC;;AAE9B;AACA;AACA;AACA;AACA,MAAMI,aAAa,CAAC;EAClB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,WAAWA,CAACC,MAAM,GAAG,CAAC,CAAC,EAAE;IACvB,IAAI,CAACC,OAAO,GACVD,MAAM,CAACC,OAAO,IAAIC,OAAO,CAACC,GAAG,CAACC,gBAAgB,IAAI,aAAa;IACjE,IAAI,CAACC,MAAM,GAAGL,MAAM,CAACK,MAAM,IAAIH,OAAO,CAACC,GAAG,CAACG,QAAQ,IAAI,cAAc;IACrE,IAAI,CAACC,WAAW,GACdP,MAAM,CAACO,WAAW,IAClBL,OAAO,CAACC,GAAG,CAACK,uBAAuB,IACnC,2BAA2B;IAC7B,IAAI,CAACC,OAAO,GAAGT,MAAM,CAACS,OAAO,IAAIP,OAAO,CAACC,GAAG,CAACO,eAAe,KAAK,MAAM;IACvE,IAAI,CAACC,SAAS,GACZX,MAAM,CAACW,SAAS,IAAIT,OAAO,CAACC,GAAG,CAACS,kBAAkB,KAAK,MAAM;IAC/D,IAAI,CAACC,cAAc,GACjBb,MAAM,CAACa,cAAc,IAAIX,OAAO,CAACC,GAAG,CAACW,uBAAuB,IAAI,EAAE;IACpE,IAAI,CAACC,eAAe,GAClBf,MAAM,CAACe,eAAe,IAAIb,OAAO,CAACC,GAAG,CAACa,wBAAwB,IAAI,EAAE;IACtE,IAAI,CAACC,mBAAmB,GACtBjB,MAAM,CAACiB,mBAAmB,IAC1Bf,OAAO,CAACC,GAAG,CAACe,4BAA4B,IACxC,EAAE;IACJ,IAAI,CAACC,WAAW,GACdnB,MAAM,CAACmB,WAAW,IAClBC,QAAQ,CAAClB,OAAO,CAACC,GAAG,CAACkB,oBAAoB,IAAI,EAAE,EAAE,EAAE,CAAC,IACpD,EAAE;IAEJ,IAAI,CAACC,UAAU,GAAG,IAAI,IAAI,CAACf,WAAW,MAAM,IAAI,CAACN,OAAO,MAAM,IAAI,CAACI,MAAM,gBAAgB;IAEzF,IAAI,CAACkB,QAAQ,GAAG,IAAI9B,MAAM,CAAC+B,QAAQ,CAAC,CAAC;IACrC/B,MAAM,CAACgC,qBAAqB,CAAC;MAAEC,QAAQ,EAAE,IAAI,CAACH;IAAS,CAAC,CAAC;IAEzD,IAAI,CAACI,aAAa,GAAG;MACnBC,GAAG,EAAE,IAAI,CAAC3B,OAAO;MACjB4B,OAAO,EAAE,IAAI,CAACxB,MAAM;MACpByB,YAAY,EAAE,IAAI,CAACvB;IACrB,CAAC;IAED,MAAMwB,SAAS,GAAGC,MAAM,CAACC,IAAI,CAC3B,GAAG,IAAI,CAAClB,eAAe,IAAI,IAAI,CAACE,mBAAmB,EACrD,CAAC,CAACiB,QAAQ,CAAC,QAAQ,CAAC;IACpB,IAAI,CAACC,OAAO,GAAG,IAAI1C,MAAM,CAAC2C,WAAW,CACnC,IAAI,CAACvB,cAAc,EACnB;MACEwB,OAAO,EAAE;QAAEC,aAAa,EAAE,SAASP,SAAS;MAAG,CAAC;MAChDQ,KAAK,EAAE,IAAI1C,KAAK,CAAC2C,KAAK,CAAC;QAAEC,SAAS,EAAE;MAAK,CAAC;IAC5C,CAAC,EACD,IAAI,CAAClB,QACP,CAAC;IAED,IAAI,CAACmB,MAAM,GAAG,CAAC,CAAC;IAChB,IAAI,CAACC,QAAQ,GAAG,CAAC,CAAC;;IAElB;IACA,IAAI,CAACC,aAAa,GAAG,CAAC,CAAC;IACvB;IACA,IAAI,CAACC,eAAe,GAAG,CAAC,CAAC;IAEzB,IAAI,CAACC,gBAAgB,GAAG,CAAC;IACzB,IAAI,CAACC,cAAc,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;IAEhC,IAAI,CAACC,mBAAmB,CAAC,CAAC;IAC1B,IAAI,CAACC,mBAAmB,CAAC,CAAC;EAC5B;;EAEA;AACF;AACA;AACA;EACED,mBAAmB,GAAGA,CAAA,KAAM;IAC1B,IAAI,CAACE,WAAW,CACd,+BAA+B,EAC/B,qDAAqD,EACrD,IAAI,CAACC,kBACP,CAAC;IACD,IAAI,CAACD,WAAW,CACd,yBAAyB,EACzB,kDAAkD,EAClD,IAAI,CAACE,gBACP,CAAC;IACD,IAAI,CAACF,WAAW,CACd,kCAAkC,EAClC,yCAAyC,EACzC,IAAI,CAACG,uBACP,CAAC;IACD,IAAI,CAACH,WAAW,CACd,uBAAuB,EACvB,0CAA0C,EAC1C,IAAI,CAACI,UACP,CAAC;IACD,IAAI,CAACJ,WAAW,CACd,kCAAkC,EAClC,yDAAyD,EACzD,IAAI,CAACK,uBACP,CAAC;IACD,IAAI,CAACL,WAAW,CACd,oBAAoB,EACpB,uCAAuC,EACvClD,OAAO,CAACwD,MACV,CAAC;IAED,IAAI,CAACC,aAAa,CAChB,yBAAyB,EACzB,uDAAuD,EACvD,CACE,GAAGC,MAAM,CAACC,IAAI,CAAC,IAAI,CAAClC,aAAa,CAAC,EAClC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,CAEjB,CAAC;EACH,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEyB,WAAW,GAAGA,CACZU,IAAI,EACJC,IAAI,EACJC,QAAQ,EACRC,UAAU,GAAGL,MAAM,CAACC,IAAI,CAAC,IAAI,CAAClC,aAAa,CAAC,KACzC;IACH,IAAI,IAAI,CAACe,MAAM,CAACoB,IAAI,CAAC,EAAE,OAAO,IAAI,CAACpB,MAAM,CAACoB,IAAI,CAAC;IAE/C,MAAMI,CAAC,GAAG,IAAIzE,MAAM,CAAC0E,KAAK,CAAC;MACzBL,IAAI;MACJC,IAAI;MACJE,UAAU;MACVG,SAAS,EAAE,CAAC,IAAI,CAAC7C,QAAQ;IAC3B,CAAC,CAAC;IACF,IAAI,CAACmB,MAAM,CAACoB,IAAI,CAAC,GAAGI,CAAC;IAErB,IAAI,OAAOF,QAAQ,KAAK,UAAU,EAAE,IAAI,CAACpB,aAAa,CAACkB,IAAI,CAAC,GAAGE,QAAQ;IAEvE,OAAOE,CAAC;EACV,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEP,aAAaA,CAACG,IAAI,EAAEC,IAAI,EAAEE,UAAU,GAAGL,MAAM,CAACC,IAAI,CAAC,IAAI,CAAClC,aAAa,CAAC,EAAE;IACtE,IAAI,IAAI,CAACgB,QAAQ,CAACmB,IAAI,CAAC,EAAE,OAAO,IAAI,CAACnB,QAAQ,CAACmB,IAAI,CAAC,CAACO,SAAS;IAE7D,MAAMC,CAAC,GAAG,IAAI7E,MAAM,CAAC8E,OAAO,CAAC;MAC3BT,IAAI;MACJC,IAAI;MACJE,UAAU;MACVG,SAAS,EAAE,CAAC,IAAI,CAAC7C,QAAQ;IAC3B,CAAC,CAAC;IACF,IAAI,CAACoB,QAAQ,CAACmB,IAAI,CAAC,GAAGQ,CAAC;IAEvB,MAAMD,SAAS,GAAGA,CAACG,IAAI,GAAG,CAAC,CAAC,EAAEC,KAAK,GAAG,CAAC,KAAK;MAC1CH,CAAC,CAACI,GAAG,CAAC;QAAE,GAAG,IAAI,CAAC/C,aAAa;QAAE,GAAG6C;MAAK,CAAC,EAAEC,KAAK,CAAC;IAClD,CAAC;IAED,IAAI,CAAC9B,QAAQ,CAACmB,IAAI,CAAC,CAACO,SAAS,GAAGA,SAAS;IACzC,OAAOA,SAAS;EAClB;;EAEA;AACF;AACA;AACA;EACEhB,kBAAkB,GAAGA,CAAA,KAAM;IACzB,IAAI;MACF,MAAMsB,IAAI,GAAGhF,EAAE,CAACiF,YAAY,CAAC,yBAAyB,EAAE,OAAO,CAAC;MAChE,MAAMC,KAAK,GAAGF,IAAI,CAACE,KAAK,CAAC,kBAAkB,CAAC;MAC5C,IAAI,CAACA,KAAK,EAAE,OAAO,CAAC;MAEpB,MAAM5B,GAAG,GAAGD,IAAI,CAACC,GAAG,CAAC,CAAC;MACtB,MAAM6B,YAAY,GAAG1D,QAAQ,CAACyD,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;MAE3C,IAAI,IAAI,CAAC/B,gBAAgB,KAAK,CAAC,EAAE;QAC/B,IAAI,CAACA,gBAAgB,GAAGgC,YAAY;QACpC,IAAI,CAAC/B,cAAc,GAAGE,GAAG;QACzB,OAAO,CAAC;MACV;MAEA,MAAM8B,UAAU,GAAGD,YAAY,GAAG,IAAI,CAAChC,gBAAgB;MACvD,MAAMkC,SAAS,GAAG/B,GAAG,GAAG,IAAI,CAACF,cAAc;MAE3C,IAAI,CAACD,gBAAgB,GAAGgC,YAAY;MACpC,IAAI,CAAC/B,cAAc,GAAGE,GAAG;MAEzB,OAAQ8B,UAAU,IAAIC,SAAS,GAAG,IAAI,CAAC,GAAI,GAAG;IAChD,CAAC,CAAC,MAAM;MACN,OAAO,CAAC;IACV;EACF,CAAC;;EAED;AACF;AACA;AACA;EACE1B,gBAAgBA,CAAA,EAAG;IACjB,IAAI;MACF,MAAM2B,UAAU,GAAG,wBAAwB;MAC3C,IAAItF,EAAE,CAACuF,UAAU,CAACD,UAAU,CAAC,EAAE;QAC7B,MAAM,CAACE,QAAQ,EAAEC,SAAS,CAAC,GAAGzF,EAAE,CAC7BiF,YAAY,CAACK,UAAU,EAAE,MAAM,CAAC,CAChCI,IAAI,CAAC,CAAC,CACNC,KAAK,CAAC,GAAG,CAAC;QACb,IAAIH,QAAQ,KAAK,KAAK,EAAE,OAAOvF,EAAE,CAAC2F,IAAI,CAAC,CAAC,CAACC,MAAM;QAC/C,OAAOpE,QAAQ,CAAC+D,QAAQ,EAAE,EAAE,CAAC,GAAG/D,QAAQ,CAACgE,SAAS,EAAE,EAAE,CAAC;MACzD;MACA,OAAOxF,EAAE,CAAC2F,IAAI,CAAC,CAAC,CAACC,MAAM;IACzB,CAAC,CAAC,MAAM;MACN,OAAO,CAAC;IACV;EACF;;EAEA;AACF;AACA;AACA;EACEjC,uBAAuBA,CAAA,EAAG;IACxB,IAAI;MACF,OAAOnC,QAAQ,CACbzB,EAAE,CAACiF,YAAY,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAACS,IAAI,CAAC,CAAC,EAChE,EACF,CAAC;IACH,CAAC,CAAC,MAAM;MACN,OAAOnF,OAAO,CAACuF,WAAW,CAAC,CAAC,CAACC,GAAG;IAClC;EACF;;EAEA;AACF;AACA;AACA;EACEjC,uBAAuBA,CAAA,EAAG;IACxB,IAAI;MACF,MAAMkC,IAAI,GAAG,2BAA2B;MACxC,IAAIhG,EAAE,CAACuF,UAAU,CAACS,IAAI,CAAC,EAAE;QACvB,MAAMC,GAAG,GAAGjG,EAAE,CAACiF,YAAY,CAACe,IAAI,EAAE,OAAO,CAAC,CAACN,IAAI,CAAC,CAAC;QACjD,IAAIO,GAAG,KAAK,KAAK,EAAE;UACjB,MAAMC,MAAM,GAAGzE,QAAQ,CAACwE,GAAG,EAAE,EAAE,CAAC;UAChC,IAAIC,MAAM,IAAIA,MAAM,GAAGjG,EAAE,CAACkG,QAAQ,CAAC,CAAC,EAAE,OAAOD,MAAM;QACrD;MACF;MACA,OAAOjG,EAAE,CAACkG,QAAQ,CAAC,CAAC;IACtB,CAAC,CAAC,MAAM;MACN,OAAOlG,EAAE,CAACkG,QAAQ,CAAC,CAAC;IACtB;EACF;;EAEA;AACF;AACA;AACA;EACEtC,UAAUA,CAAA,EAAG;IACX,OAAO,IAAIuC,OAAO,CAACC,OAAO,IAAI;MAC5B,MAAMC,KAAK,GAAGjD,IAAI,CAACC,GAAG,CAAC,CAAC;MACxBiD,YAAY,CAAC,MAAMF,OAAO,CAAChD,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGgD,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;AACA;EACEE,0BAA0B,GAAGA,CAACC,GAAG,EAAEC,GAAG,EAAEC,IAAI,KAAK;IAC/C,MAAML,KAAK,GAAGjD,IAAI,CAACC,GAAG,CAAC,CAAC;IACxBoD,GAAG,CAACE,EAAE,CAAC,QAAQ,EAAE,MAAM;MACrB,MAAMC,KAAK,GAAGJ,GAAG,CAACI,KAAK,EAAEb,IAAI,IAAIS,GAAG,CAACT,IAAI,IAAI,SAAS;MACtD,MAAMc,KAAK,GACTL,GAAG,CAACM,MAAM,EAAED,KAAK,IAAIL,GAAG,CAACO,IAAI,EAAEF,KAAK,IAAIL,GAAG,CAACQ,KAAK,EAAEH,KAAK,IAAI,EAAE;MAChE,MAAMI,UAAU,GACdT,GAAG,CAACM,MAAM,EAAEG,UAAU,IACtBT,GAAG,CAACO,IAAI,EAAEE,UAAU,IACpBT,GAAG,CAACQ,KAAK,EAAEC,UAAU,IACrB,EAAE;MAEJ,IAAI,CAAClE,QAAQ,EAAEmE,uBAAuB,EAAEzC,SAAS,CAAC;QAChD0C,MAAM,EAAEX,GAAG,CAACW,MAAM;QAClBP,KAAK;QACLQ,WAAW,EAAEX,GAAG,CAACY,UAAU;QAC3BR,KAAK;QACLI,UAAU;QACVK,QAAQ,EAAElE,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGgD,KAAK;QAC5BkB,WAAW,EAAEf,GAAG,CAAC/D,OAAO,CAAC,gBAAgB,CAAC,GACtCjB,QAAQ,CAACgF,GAAG,CAAC/D,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,GAC3C;MACN,CAAC,CAAC;IACJ,CAAC,CAAC;IAEFiE,IAAI,CAAC,CAAC;EACR,CAAC;;EAED;AACF;AACA;EACEc,WAAW,GAAG,MAAAA,CAAA,KAAY;IACxB,IAAI;MACF,KAAK,MAAM,CAACtD,IAAI,EAAEE,QAAQ,CAAC,IAAIJ,MAAM,CAACyD,OAAO,CAAC,IAAI,CAACzE,aAAa,CAAC,EAAE;QACjE,IAAI;UACF,MAAM0E,MAAM,GAAGtD,QAAQ,CAAC,CAAC;UACzB,MAAM4B,GAAG,GAAG0B,MAAM,YAAYvB,OAAO,GAAG,MAAMuB,MAAM,GAAGA,MAAM;UAC7D,IAAI1B,GAAG,KAAK2B,SAAS,EAAE,IAAI,CAAC7E,MAAM,CAACoB,IAAI,CAAC,CAAC0D,GAAG,CAAC,IAAI,CAAC7F,aAAa,EAAEiE,GAAG,CAAC;QACvE,CAAC,CAAC,OAAO6B,GAAG,EAAE;UACZC,OAAO,CAACC,KAAK,CACX,GAAG,IAAI,CAACrG,UAAU,2BAA2BwC,IAAI,GAAG,EACpD2D,GACF,CAAC;QACH;MACF;MAEA,MAAM,IAAI,CAACtF,OAAO,CAACyF,IAAI,CAAC;QACtBC,OAAO,EAAE,IAAI,CAAC5H,OAAO;QACrB6H,SAAS,EAAE;UAAEhG,YAAY,EAAE,IAAI,CAACvB,WAAW;UAAEwH,QAAQ,EAAE,IAAI,CAAC1H;QAAO;MACrE,CAAC,CAAC;MAEFuD,MAAM,CAACoE,MAAM,CAAC,IAAI,CAACrF,QAAQ,CAAC,CAACsF,OAAO,CAACC,OAAO,IAAIA,OAAO,CAACC,KAAK,CAAC,CAAC,CAAC;MAEhE,IAAI,IAAI,CAACxH,SAAS,EAAE;QAClB,MAAMyH,OAAO,GAAG,MAAM,IAAI,CAAC7G,QAAQ,CAAC8G,gBAAgB,CAAC,CAAC;QACtDX,OAAO,CAACY,GAAG,CACT,GAAG,IAAI,CAAChH,UAAU,aAAa,EAC/BiH,IAAI,CAACC,SAAS,CAACJ,OAAO,EAAE,IAAI,EAAE,CAAC,CACjC,CAAC;MACH;IACF,CAAC,CAAC,OAAOX,GAAG,EAAE;MACZC,OAAO,CAACC,KAAK,CAAC,GAAG,IAAI,CAACrG,UAAU,0BAA0B,EAAEmG,GAAG,CAAC;IAClE;EACF,CAAC;;EAED;AACF;AACA;AACA;EACEgB,SAAS,GAAGA,CAACC,QAAQ,GAAG,IAAI,CAACvH,WAAW,KAAK;IAC3C,IAAI,CAAC,IAAI,CAACV,OAAO,EAAE;MACjBiH,OAAO,CAACiB,IAAI,CAAC,GAAG,IAAI,CAACrH,UAAU,mBAAmB,CAAC;IACrD;IAEAsH,WAAW,CAAC,MAAM;MAChB,IAAI,CAACxB,WAAW,CAAC,CAAC,CAACyB,KAAK,CAACpB,GAAG,IAAI;QAC9BC,OAAO,CAACC,KAAK,CAAC,GAAG,IAAI,CAACrG,UAAU,0BAA0B,EAAEmG,GAAG,CAAC;MAClE,CAAC,CAAC;IACJ,CAAC,EAAEiB,QAAQ,GAAG,IAAI,CAAC;IAEnBhB,OAAO,CAACiB,IAAI,CAAC,GAAG,IAAI,CAACrH,UAAU,8BAA8B,CAAC;EAChE,CAAC;EAEDwH,OAAO,GAAG,MAAAA,CAAA,KAAY;IACpB,IAAI,IAAI,CAACrI,OAAO,EAAE;MAChB,MAAM,IAAI,CAAC0B,OAAO,CAAC4G,MAAM,CAAC;QACxBlB,OAAO,EAAE,IAAI,CAAC5H,OAAO;QACrB6H,SAAS,EAAE;UACThG,YAAY,EAAE,IAAI,CAACvB,WAAW;UAC9BwH,QAAQ,EAAE,IAAI,CAAC1H;QACjB;MACF,CAAC,CAAC;IACJ;IACAH,OAAO,CAAC8I,IAAI,CAAC,CAAC,CAAC;EACjB,CAAC;EAGD7F,mBAAmB,GAAGA,CAAA,KAAO;IAC3BjD,OAAO,CAACqG,EAAE,CAAC,QAAQ,EAAE,IAAI,CAACuC,OAAO,CAAC;IAClC5I,OAAO,CAACqG,EAAE,CAAC,SAAS,EAAE,IAAI,CAACuC,OAAO,CAAC;EACrC,CAAC;AACH;AAEAG,MAAM,CAACC,OAAO,GAAG;EAAEpJ;AAAc,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"metricsClient.js","names":["client","require","fs","os","https","MetricsClient","constructor","config","appName","process","env","METRICS_APP_NAME","dynoId","HOSTNAME","processType","BUILD_DYNO_PROCESS_TYPE","enabled","METRICS_ENABLED","logValues","METRICS_LOG_VALUES","pushgatewayUrl","METRICS_PUSHGATEWAY_URL","pushgatewayUser","METRICS_PUSHGATEWAY_USER","pushgatewayPassword","METRICS_PUSHGATEWAY_PASSWORD","intervalSec","parseInt","METRICS_INTERVAL_SEC","prefixLogs","registry","Registry","collectDefaultMetrics","register","defaultLabels","app","dyno_id","process_type","authToken","Buffer","from","toString","gateway","Pushgateway","headers","Authorization","agent","Agent","keepAlive","gauges","counters","gaugeUpdaters","_lastUsageMicros","_lastCheckTime","Date","now","_clearOldWorkers","then","_","_initDefaultMetrics","_setCleanupHandlers","createGauge","getCpuUsagePercent","getAvailableCPUs","getContainerMemoryUsage","measureLag","getContainerMemoryLimit","uptime","createCounter","Object","keys","name","help","updateFn","labelNames","g","Gauge","registers","triggerFn","c","Counter","data","value","inc","stat","readFileSync","match","currentUsage","deltaUsage","deltaTime","cpuMaxPath","existsSync","quotaStr","periodStr","trim","split","cpus","length","memoryUsage","rss","path","val","parsed","totalmem","Promise","resolve","start","setImmediate","countHttpRequestMiddleware","req","res","next","on","route","appId","params","body","query","databaseId","app_http_requests_total","method","status_code","statusCode","duration","requestSize","pushMetrics","entries","result","undefined","set","err","console","error","push","jobName","groupings","instance","values","forEach","counter","reset","metrics","getMetricsAsJSON","log","JSON","stringify","startPush","interval","warn","setInterval","catch","cleanup","delete","exit","module","exports"],"sources":["../src/metricsClient.js"],"sourcesContent":["const client = require('prom-client')\nconst fs = require('fs')\nconst os = require('os')\nconst https = require('https')\n\n/**\n * MetricsClient handles Prometheus metrics collection and push.\n * Supports gauges, counters, default metrics, and custom metrics.\n */\nclass MetricsClient {\n /**\n * @param {Object} config\n * @param {string} [config.appName] Name of the application\n * @param {string} [config.dynoId] Dyno/instance ID\n * @param {string} [config.processType] Process type (web, worker, etc.)\n * @param {boolean} [config.enabled] Enable metrics collection\n * @param {boolean} [config.logValues] Log metrics values to console\n * @param {string} [config.pushgatewayUrl] PushGateway URL\n * @param {string} [config.pushgatewayUser] PushGateway username\n * @param {string} [config.pushgatewayPassword] PushGateway password\n * @param {number} [config.intervalSec] Interval in seconds for pushing metrics\n */\n constructor(config = {}) {\n this.appName =\n config.appName || process.env.METRICS_APP_NAME || 'unknown-app'\n this.dynoId = config.dynoId || process.env.HOSTNAME || 'unknown-dyno'\n this.processType =\n config.processType ||\n process.env.BUILD_DYNO_PROCESS_TYPE ||\n 'undefined_build_dyno_type'\n this.enabled = config.enabled ?? process.env.METRICS_ENABLED === 'true'\n this.logValues =\n config.logValues ?? process.env.METRICS_LOG_VALUES === 'true'\n this.pushgatewayUrl =\n config.pushgatewayUrl || process.env.METRICS_PUSHGATEWAY_URL || ''\n this.pushgatewayUser =\n config.pushgatewayUser || process.env.METRICS_PUSHGATEWAY_USER || ''\n this.pushgatewayPassword =\n config.pushgatewayPassword ||\n process.env.METRICS_PUSHGATEWAY_PASSWORD ||\n ''\n this.intervalSec =\n config.intervalSec ||\n parseInt(process.env.METRICS_INTERVAL_SEC || '', 10) ||\n 15\n\n this.prefixLogs = `[${this.processType}] [${this.appName}] [${this.dynoId}] [Monitoring]`\n\n this.registry = new client.Registry()\n client.collectDefaultMetrics({ register: this.registry })\n\n this.defaultLabels = {\n app: this.appName,\n dyno_id: this.dynoId,\n process_type: this.processType,\n }\n\n const authToken = Buffer.from(\n `${this.pushgatewayUser}:${this.pushgatewayPassword}`\n ).toString('base64')\n this.gateway = new client.Pushgateway(\n this.pushgatewayUrl,\n {\n headers: { Authorization: `Basic ${authToken}` },\n agent: new https.Agent({ keepAlive: true }),\n },\n this.registry\n )\n\n this.gauges = {}\n this.counters = {}\n\n /** @type {Object<string, function(): number | Promise<number>>} */\n this.gaugeUpdaters = {}\n this._lastUsageMicros = 0\n this._lastCheckTime = Date.now()\n this._clearOldWorkers().then(_ => {\n this._initDefaultMetrics()\n this._setCleanupHandlers()\n })\n }\n\n /**\n * Register default gauges and counters.\n * @private\n */\n _initDefaultMetrics = () => {\n this.createGauge(\n 'app_process_cpu_usage_percent',\n 'Current CPU usage of the Node.js process in percent',\n this.getCpuUsagePercent\n )\n this.createGauge(\n 'app_available_cpu_count',\n 'How many CPU cores are available to this process',\n this.getAvailableCPUs\n )\n this.createGauge(\n 'app_container_memory_usage_bytes',\n 'Current container RAM usage from cgroup',\n this.getContainerMemoryUsage\n )\n this.createGauge(\n 'app_event_loop_lag_ms',\n 'Estimated event loop lag in milliseconds',\n this.measureLag\n )\n this.createGauge(\n 'app_container_memory_limit_bytes',\n 'Max RAM available to container from cgroup (memory.max)',\n this.getContainerMemoryLimit\n )\n this.createGauge(\n 'app_uptime_seconds',\n 'How long the process has been running',\n process.uptime\n )\n\n this.createCounter(\n 'app_http_requests_total',\n 'Total number of HTTP requests handled by this process',\n [\n ...Object.keys(this.defaultLabels),\n 'method',\n 'route',\n 'appId',\n 'databaseId',\n 'duration',\n 'requestSize',\n 'status_code',\n ]\n )\n }\n\n /**\n * Create a gauge metric.\n * @param {string} name\n * @param {string} help\n * @param {function(): number|Promise<number>} [updateFn] Optional function returning value\n * @param {string[]} [labelNames]\n * @returns {client.Gauge}\n */\n createGauge = (\n name,\n help,\n updateFn,\n labelNames = Object.keys(this.defaultLabels)\n ) => {\n if (this.gauges[name]) return this.gauges[name]\n\n const g = new client.Gauge({\n name,\n help,\n labelNames,\n registers: [this.registry],\n })\n this.gauges[name] = g\n\n if (typeof updateFn === 'function') this.gaugeUpdaters[name] = updateFn\n\n return g\n }\n\n /**\n * Create a counter metric.\n * Returns a trigger function to increment the counter manually.\n * @param {string} name\n * @param {string} help\n * @param {string[]} [labelNames]\n * @returns {function(data?: object, value?: number): void} triggerFn\n */\n createCounter(name, help, labelNames = Object.keys(this.defaultLabels)) {\n if (this.counters[name]) return this.counters[name].triggerFn\n\n const c = new client.Counter({\n name,\n help,\n labelNames,\n registers: [this.registry],\n })\n this.counters[name] = c\n\n const triggerFn = (data = {}, value = 1) => {\n c.inc({ ...this.defaultLabels, ...data }, value)\n }\n\n this.counters[name].triggerFn = triggerFn\n return triggerFn\n }\n\n /**\n * Get CPU usage percent (cgroup-aware)\n * @returns {number}\n */\n getCpuUsagePercent = () => {\n try {\n const stat = fs.readFileSync('/sys/fs/cgroup/cpu.stat', 'utf-8')\n const match = stat.match(/usage_usec (\\d+)/)\n if (!match) return 0\n\n const now = Date.now()\n const currentUsage = parseInt(match[1], 10)\n\n if (this._lastUsageMicros === 0) {\n this._lastUsageMicros = currentUsage\n this._lastCheckTime = now\n return 0\n }\n\n const deltaUsage = currentUsage - this._lastUsageMicros\n const deltaTime = now - this._lastCheckTime\n\n this._lastUsageMicros = currentUsage\n this._lastCheckTime = now\n\n return (deltaUsage / (deltaTime * 1000)) * 100\n } catch {\n return 0\n }\n }\n\n /**\n * Get available CPU cores.\n * @returns {number}\n */\n getAvailableCPUs() {\n try {\n const cpuMaxPath = '/sys/fs/cgroup/cpu.max'\n if (fs.existsSync(cpuMaxPath)) {\n const [quotaStr, periodStr] = fs\n .readFileSync(cpuMaxPath, 'utf8')\n .trim()\n .split(' ')\n if (quotaStr === 'max') return os.cpus().length\n return parseInt(quotaStr, 10) / parseInt(periodStr, 10)\n }\n return os.cpus().length\n } catch {\n return 1\n }\n }\n\n /**\n * Get container memory usage in bytes.\n * @returns {number}\n */\n getContainerMemoryUsage() {\n try {\n return parseInt(\n fs.readFileSync('/sys/fs/cgroup/memory.current', 'utf-8').trim(),\n 10\n )\n } catch {\n return process.memoryUsage().rss\n }\n }\n\n /**\n * Get container memory limit in bytes.\n * @returns {number}\n */\n getContainerMemoryLimit() {\n try {\n const path = '/sys/fs/cgroup/memory.max'\n if (fs.existsSync(path)) {\n const val = fs.readFileSync(path, 'utf-8').trim()\n if (val !== 'max') {\n const parsed = parseInt(val, 10)\n if (parsed && parsed < os.totalmem()) return parsed\n }\n }\n return os.totalmem()\n } catch {\n return os.totalmem()\n }\n }\n\n /**\n * Measure event loop lag in ms.\n * @returns {Promise<number>}\n */\n measureLag() {\n return new Promise(resolve => {\n const start = Date.now()\n setImmediate(() => resolve(Date.now() - start))\n })\n }\n\n /**\n * Express middleware to count HTTP requests.\n * Increments the `app_http_requests_total` counter.\n */\n countHttpRequestMiddleware = (req, res, next) => {\n const start = Date.now()\n res.on('finish', () => {\n const route = req.route?.path || req.path || 'unknown'\n const appId =\n req.params?.appId || req.body?.appId || req.query?.appId || ''\n const databaseId =\n req.params?.databaseId ||\n req.body?.databaseId ||\n req.query?.databaseId ||\n ''\n\n this.counters?.app_http_requests_total?.triggerFn({\n method: req.method,\n route,\n status_code: res.statusCode,\n appId,\n databaseId,\n duration: Date.now() - start,\n requestSize: req.headers['content-length']\n ? parseInt(req.headers['content-length'], 10)\n : 0,\n })\n })\n\n next()\n }\n\n /**\n * Push all gauges and counters to PushGateway and optionally log.\n */\n pushMetrics = async () => {\n try {\n for (const [name, updateFn] of Object.entries(this.gaugeUpdaters)) {\n try {\n const result = updateFn()\n const val = result instanceof Promise ? await result : result\n if (val !== undefined) this.gauges[name].set(this.defaultLabels, val)\n } catch (err) {\n console.error(\n `${this.prefixLogs} Failed to update gauge ${name}:`,\n err\n )\n }\n }\n\n await this.gateway.push({\n jobName: this.appName,\n groupings: { process_type: this.processType, instance: this.dynoId },\n })\n\n Object.values(this.counters).forEach(counter => counter.reset())\n\n if (this.logValues) {\n const metrics = await this.registry.getMetricsAsJSON()\n console.log(\n `${this.prefixLogs} Metrics:\\n`,\n JSON.stringify(metrics, null, 2)\n )\n }\n } catch (err) {\n console.error(`${this.prefixLogs} Failed to push metrics:`, err)\n }\n }\n\n /**\n * Start automatic periodic push of metrics.\n * @param {number} [interval] Interval in seconds\n */\n startPush = (interval = this.intervalSec) => {\n if (!this.enabled) {\n console.warn(`${this.prefixLogs} Metrics disabled`)\n }\n\n setInterval(() => {\n this.pushMetrics().catch(err => {\n console.error(`${this.prefixLogs} Failed to push metrics:`, err)\n })\n }, interval * 1000)\n\n console.warn(`${this.prefixLogs} Metrics collection started.`)\n }\n\n cleanup = async () => {\n if (this.enabled) {\n await this.gateway.delete({\n jobName: this.appName,\n groupings: {\n process_type: this.processType,\n instance: this.dynoId,\n },\n })\n }\n process.exit(0)\n }\n\n _clearOldWorkers = async () => {\n try {\n await this.gateway.delete({\n jobName: this.appName,\n })\n console.warn(`${this.prefixLogs} Cleared all old workers metrics.`)\n } catch (err) {\n console.error(`${this.prefixLogs} Failed to clear old metrics:`, err)\n }\n }\n\n _setCleanupHandlers = () => {\n process.on('SIGINT', this.cleanup)\n process.on('SIGTERM', this.cleanup)\n }\n}\n\nmodule.exports = { MetricsClient }\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.3",
3
+ "version": "0.1.5",
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",
@@ -72,14 +72,12 @@ class MetricsClient {
72
72
 
73
73
  /** @type {Object<string, function(): number | Promise<number>>} */
74
74
  this.gaugeUpdaters = {}
75
- /** @type {Object<string, function(data?: object, value?: number): void>} */
76
- this.counterUpdaters = {}
77
-
78
75
  this._lastUsageMicros = 0
79
76
  this._lastCheckTime = Date.now()
80
-
81
- this._initDefaultMetrics()
82
- this._setCleanupHandlers()
77
+ this._clearOldWorkers().then(_ => {
78
+ this._initDefaultMetrics()
79
+ this._setCleanupHandlers()
80
+ })
83
81
  }
84
82
 
85
83
  /**
@@ -388,8 +386,18 @@ class MetricsClient {
388
386
  process.exit(0)
389
387
  }
390
388
 
389
+ _clearOldWorkers = async () => {
390
+ try {
391
+ await this.gateway.delete({
392
+ jobName: this.appName,
393
+ })
394
+ console.warn(`${this.prefixLogs} Cleared all old workers metrics.`)
395
+ } catch (err) {
396
+ console.error(`${this.prefixLogs} Failed to clear old metrics:`, err)
397
+ }
398
+ }
391
399
 
392
- _setCleanupHandlers = () => {
400
+ _setCleanupHandlers = () => {
393
401
  process.on('SIGINT', this.cleanup)
394
402
  process.on('SIGTERM', this.cleanup)
395
403
  }