@adalo/metrics 0.0.0-staging.14 → 0.0.0-staging.15
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metricsClient.d.ts","sourceRoot":"","sources":["../../src/metrics/metricsClient.js"],"names":[],"mappings":"AA6BA;;;;;;GAMG;AACH;IACE;;;;;;;;;;;;;;;;;OAiBG;IACH;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"metricsClient.d.ts","sourceRoot":"","sources":["../../src/metrics/metricsClient.js"],"names":[],"mappings":"AA6BA;;;;;;GAMG;AACH;IACE;;;;;;;;;;;;;;;;;OAiBG;IACH;;;;;;;;;;;;;;;;mBA4FC;IA/CC,4BAA4C;IAC5C,qCAA8D;IAM9D,8CAOU;IAEV,oCAEC;IAED,6BAA2D;IAG3D,iCAAwE;IACxE,+BAA8C;IAgB9C,kCAAqC;IAErC,yBAAyB;IACzB,uBAAgC;IAMlC,iCAaC;IAED,2CAEC;IAED,gCAiFC;IAED,iCAyBC;IAED,2BAeC;IAED,kCASC;IAED,kCAcC;IAED,2BAKC;IAED;;;;;;;aAuCC;IAED;;;;;OAKG;IACH,sEAHiB,IAAI,GAAG,QAAQ,IAAI,CAAC,kBACxB,IAAI,CAoBhB;IAuBD,oEA+BC;CACF"}
|
|
@@ -60,8 +60,18 @@ class MetricsClient extends BaseMetricsClient {
|
|
|
60
60
|
*/
|
|
61
61
|
constructor(config = {}) {
|
|
62
62
|
const processTypeBeforeSuper = config.processType || process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined_build_dyno_type';
|
|
63
|
-
const httpMetricsEnabled = config.httpMetricsEnabled ?? process.env.METRICS_HTTP_ENABLED === 'true' ?? false;
|
|
64
63
|
const redisUrl = config.httpMetricsRedisUrl || process.env.METRICS_HTTP_REDIS_URL || process.env.REDIS_URL || '';
|
|
64
|
+
let httpMetricsEnabled;
|
|
65
|
+
if (config.httpMetricsEnabled !== undefined) {
|
|
66
|
+
httpMetricsEnabled = config.httpMetricsEnabled;
|
|
67
|
+
} else if (process.env.METRICS_HTTP_ENABLED === 'true') {
|
|
68
|
+
httpMetricsEnabled = true;
|
|
69
|
+
} else if (isMetricsExporterProcessType(processTypeBeforeSuper) && redisUrl) {
|
|
70
|
+
// metrics: dyno must drain Redis HTTP keys; many stacks omit METRICS_HTTP_ENABLED here
|
|
71
|
+
httpMetricsEnabled = true;
|
|
72
|
+
} else {
|
|
73
|
+
httpMetricsEnabled = false;
|
|
74
|
+
}
|
|
65
75
|
let httpMetricsRedisAggregation = Boolean(redisUrl) && Boolean(httpMetricsEnabled) && config.httpMetricsRedisAggregation !== false;
|
|
66
76
|
if (httpMetricsRedisAggregation && !isRedisPeerInstalled()) {
|
|
67
77
|
console.warn('[MetricsClient] METRICS_HTTP_ENABLED with REDIS_URL needs the peer package `redis` in your application (npm install redis@3). Falling back to in-process HTTP counters. @adalo/metrics does not bundle redis.');
|
|
@@ -112,7 +122,8 @@ class MetricsClient extends BaseMetricsClient {
|
|
|
112
122
|
return;
|
|
113
123
|
}
|
|
114
124
|
const wc = process.env.WEB_CONCURRENCY || '';
|
|
115
|
-
|
|
125
|
+
const httpMode = !this.httpMetricsEnabled ? 'off' : this._httpRedisStore ? 'redis' : 'local_counters';
|
|
126
|
+
console.warn(`${this.prefixLogs} metrics bootstrap WEB_CONCURRENCY=${wc || '(unset)'} host_cpus=${this._bootstrapHostCpuCount} dyno_id=${this.dynoId} process_type=${this.processType} scheduling_id=${process.env.DYNO || 'n/a'} http_metrics=${httpMode} redis_http=${this.httpMetricsRedisAggregation} web_redis_only=${this._webRedisHttpRecordingOnly}`);
|
|
116
127
|
};
|
|
117
128
|
get isWebRedisHttpRecordingOnly() {
|
|
118
129
|
return Boolean(this._webRedisHttpRecordingOnly);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metricsClient.js","names":["fs","require","os","BaseMetricsClient","shouldRunMetricsPush","HttpMetricsRedisStore","isRedisPeerInstalled","isWebServingDynoContext","processType","dyno","process","env","DYNO","test","isMetricsExporterProcessType","MetricsClient","constructor","config","processTypeBeforeSuper","BUILD_DYNO_PROCESS_TYPE","httpMetricsEnabled","METRICS_HTTP_ENABLED","redisUrl","httpMetricsRedisUrl","METRICS_HTTP_REDIS_URL","REDIS_URL","httpMetricsRedisAggregation","Boolean","console","warn","isWebCtx","webRedisRecordingOnly","NODE_ENV","includeNodeDefaultMetrics","redisKeyProcessType","_httpRedisStore","appName","_webRedisHttpRecordingOnly","exportRuntimeGauges","wcParsed","parseInt","WEB_CONCURRENCY","_bootstrapWebConcurrency","Number","isFinite","_bootstrapHostCpuCount","cpus","length","defaultLabelsWithoutDynoId","app","process_type","_skippedPushWorkerLogged","_lastUsageMicros","_lastCheckTime","Date","now","_initDefaultMetrics","_logMetricsBootstrap","enabled","wc","prefixLogs","isWebRedisHttpRecordingOnly","createGauge","name","help","updateFn","getCpuUsagePercent","getAvailableCPUs","getContainerMemoryUsage","measureLag","getContainerMemoryLimit","uptime","registerHttpCounters","createCounter","labelNames","withDefaultLabelsWithoutDynoId","useLabelsWithoutDynoId","stat","readFileSync","match","currentUsage","deltaUsage","deltaTime","cpuMaxPath","existsSync","quotaStr","periodStr","trim","split","memoryUsage","rss","path","val","parsed","totalmem","Promise","resolve","start","setImmediate","trackHttpRequest","method","route","status_code","appId","databaseId","duration","record","countersFunctions","app_requests_total","app_requests_total_duration","startPush","interval","customPushMetrics","METRICS_SUPPRESS_SKIP_PUSH_LOG","_startPush","pushMetrics","flushToCounters","labels","value","trackHttpRequestMiddleware","req","res","next","on","params","body","query","datasourceId","statusCode","module","exports"],"sources":["../../src/metrics/metricsClient.js"],"sourcesContent":["const fs = require('fs')\nconst os = require('os')\nconst { BaseMetricsClient } = require('./baseMetricsClient')\nconst { shouldRunMetricsPush } = require('./shouldRunMetricsPush')\nconst {\n HttpMetricsRedisStore,\n isRedisPeerInstalled,\n} = require('./httpMetricsRedisStore')\n\n/**\n * Heroku-style: DYNO=web.1 → web serving; DYNO=metrics.1 → VM-agent exporter (Procfile `metrics:`).\n * Without DYNO (local Docker), falls back to BUILD_DYNO_PROCESS_TYPE === 'web'.\n */\nfunction isWebServingDynoContext(processType) {\n const dyno = process.env.DYNO || ''\n if (dyno) {\n return /^web\\./.test(dyno)\n }\n return processType === 'web'\n}\n\nfunction isMetricsExporterProcessType(processType) {\n const dyno = process.env.DYNO || ''\n if (dyno) {\n return /^metrics\\./.test(dyno)\n }\n return processType === 'metrics'\n}\n\n/**\n * MetricsClient handles Prometheus metrics collection and push.\n *\n * **Redis HTTP:** When `METRICS_HTTP_ENABLED` and a Redis URL exist, HTTP counts use Redis\n * (key segment from BUILD_APP_NAME + process type). Production **web.*** dynos only write Redis;\n * run Procfile **`metrics`** + **metrics-exporter.js** to drain and POST. Tests: `httpMetricsRedisAggregation: false`.\n */\nclass MetricsClient extends BaseMetricsClient {\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, metrics, etc.)\n * @param {boolean} [config.enabled] Enable metrics collection\n * @param {boolean} [config.httpMetricsEnabled] Enable HTTP request metrics (app_requests_total, app_requests_total_duration); defaults from METRICS_HTTP_ENABLED\n * @param {boolean} [config.logValues] Log metrics values to console\n * @param {string} [config.pushgatewayUrl] Push URL (VM-agent import endpoint)\n * @param {string} [config.pushgatewaySecret] Basic auth secret (Base64 user:password)\n * @param {number} [config.intervalSec] Interval in seconds for pushing metrics\n * @param {boolean} [config.removeOldMetrics] Enable to clear metrics by service name\n * @param {function} [config.startupValidation] Add to validate on start push\n * @param {boolean} [config.disablePushgateway] Disable pushing to VM-agent (use HTTP scraping instead)\n * @param {boolean} [config.includeNodeDefaultMetrics] Register prom-client default process metrics\n * @param {string} [config.httpMetricsRedisUrl] Overrides METRICS_HTTP_REDIS_URL / REDIS_URL for the HTTP Redis store\n * @param {boolean} [config.httpMetricsRedisAggregation] When unset, on if Redis + HTTP metrics; set false to force in-process HTTP counters only\n */\n constructor(config = {}) {\n const processTypeBeforeSuper =\n config.processType || process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined_build_dyno_type'\n\n const httpMetricsEnabled =\n config.httpMetricsEnabled ??\n process.env.METRICS_HTTP_ENABLED === 'true' ??\n false\n\n const redisUrl =\n config.httpMetricsRedisUrl ||\n process.env.METRICS_HTTP_REDIS_URL ||\n process.env.REDIS_URL ||\n ''\n\n let httpMetricsRedisAggregation =\n Boolean(redisUrl) &&\n Boolean(httpMetricsEnabled) &&\n config.httpMetricsRedisAggregation !== false\n\n if (httpMetricsRedisAggregation && !isRedisPeerInstalled()) {\n console.warn(\n '[MetricsClient] METRICS_HTTP_ENABLED with REDIS_URL needs the peer package `redis` in your application (npm install redis@3). Falling back to in-process HTTP counters. @adalo/metrics does not bundle redis.'\n )\n httpMetricsRedisAggregation = false\n }\n\n const isWebCtx = isWebServingDynoContext(processTypeBeforeSuper)\n const webRedisRecordingOnly =\n Boolean(httpMetricsRedisAggregation) &&\n isWebCtx &&\n process.env.NODE_ENV === 'production'\n\n super({\n ...config,\n ...(webRedisRecordingOnly ? { includeNodeDefaultMetrics: false } : {}),\n })\n\n this.httpMetricsEnabled = httpMetricsEnabled\n this.httpMetricsRedisAggregation = httpMetricsRedisAggregation\n\n const redisKeyProcessType = isMetricsExporterProcessType(this.processType)\n ? 'web'\n : this.processType\n\n this._httpRedisStore =\n this.httpMetricsEnabled && this.httpMetricsRedisAggregation\n ? new HttpMetricsRedisStore({\n redisUrl,\n appName: this.appName,\n processType: redisKeyProcessType,\n })\n : null\n\n this._webRedisHttpRecordingOnly = Boolean(\n webRedisRecordingOnly && this._httpRedisStore\n )\n\n this.exportRuntimeGauges = !this._webRedisHttpRecordingOnly\n\n const wcParsed = parseInt(process.env.WEB_CONCURRENCY || '', 10)\n this._bootstrapWebConcurrency = Number.isFinite(wcParsed) ? wcParsed : 0\n this._bootstrapHostCpuCount = os.cpus().length\n\n if (this.httpMetricsRedisAggregation && redisUrl) {\n if (isMetricsExporterProcessType(this.processType)) {\n this.defaultLabelsWithoutDynoId = {\n app: this.appName,\n process_type: 'web',\n }\n } else if (!this._webRedisHttpRecordingOnly) {\n this.defaultLabelsWithoutDynoId = {\n app: this.appName,\n process_type: this.processType,\n }\n }\n }\n\n this._skippedPushWorkerLogged = false\n\n this._lastUsageMicros = 0\n this._lastCheckTime = Date.now()\n\n this._initDefaultMetrics()\n this._logMetricsBootstrap()\n }\n\n _logMetricsBootstrap = () => {\n if (!this.enabled) {\n return\n }\n const wc = process.env.WEB_CONCURRENCY || ''\n console.warn(\n `${this.prefixLogs} metrics bootstrap WEB_CONCURRENCY=${wc || '(unset)'} host_cpus=${this._bootstrapHostCpuCount} dyno=${process.env.DYNO || '(unset)'} redis_http=${this.httpMetricsRedisAggregation} web_redis_only=${this._webRedisHttpRecordingOnly}`\n )\n }\n\n get isWebRedisHttpRecordingOnly() {\n return Boolean(this._webRedisHttpRecordingOnly)\n }\n\n _initDefaultMetrics = () => {\n if (this.exportRuntimeGauges) {\n this.createGauge({\n name: 'app_process_cpu_usage_percent',\n help: 'Current CPU usage of the Node.js process in percent',\n updateFn: this.getCpuUsagePercent,\n })\n\n this.createGauge({\n name: 'app_available_cpu_count',\n help: 'How many CPU cores are available to this process',\n updateFn: this.getAvailableCPUs,\n })\n\n this.createGauge({\n name: 'app_container_memory_usage_bytes',\n help: 'Current container RAM usage from cgroup',\n updateFn: this.getContainerMemoryUsage,\n })\n\n this.createGauge({\n name: 'app_event_loop_lag_ms',\n help: 'Estimated event loop lag in milliseconds',\n updateFn: this.measureLag,\n })\n\n this.createGauge({\n name: 'app_container_memory_limit_bytes',\n help: 'Max RAM available to container from cgroup (memory.max)',\n updateFn: this.getContainerMemoryLimit,\n })\n\n this.createGauge({\n name: 'app_uptime_seconds',\n help: 'How long the process has been running',\n updateFn: process.uptime,\n })\n\n this.createGauge({\n name: 'app_bootstrap_web_concurrency',\n help: 'WEB_CONCURRENCY at process start (diagnostic; 0 if unset/invalid)',\n updateFn: () => this._bootstrapWebConcurrency,\n })\n\n this.createGauge({\n name: 'app_bootstrap_host_cpu_count',\n help: 'os.cpus().length at process start (diagnostic)',\n updateFn: () => this._bootstrapHostCpuCount,\n })\n }\n\n const registerHttpCounters =\n this.httpMetricsEnabled && !this._webRedisHttpRecordingOnly\n\n if (registerHttpCounters) {\n this.createCounter({\n name: 'app_requests_total',\n help: 'Total number of HTTP requests',\n labelNames: this.withDefaultLabelsWithoutDynoId([\n 'method',\n 'route',\n 'appId',\n 'databaseId',\n 'status_code',\n ]),\n useLabelsWithoutDynoId: true,\n })\n\n this.createCounter({\n name: 'app_requests_total_duration',\n help: 'Total duration of HTTP requests in milliseconds',\n labelNames: this.withDefaultLabelsWithoutDynoId([\n 'method',\n 'route',\n 'appId',\n 'databaseId',\n 'status_code',\n ]),\n useLabelsWithoutDynoId: true,\n })\n }\n }\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 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 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 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 measureLag() {\n return new Promise(resolve => {\n const start = Date.now()\n setImmediate(() => resolve(Date.now() - start))\n })\n }\n\n trackHttpRequest({\n method,\n route,\n status_code,\n appId = '',\n databaseId = '',\n duration,\n }) {\n if (!this.httpMetricsEnabled) return\n\n if (this._httpRedisStore) {\n this._httpRedisStore.record(\n method,\n route,\n status_code,\n appId,\n databaseId,\n duration\n )\n return\n }\n\n this.countersFunctions?.app_requests_total({\n method,\n route,\n status_code,\n appId,\n databaseId,\n })\n this.countersFunctions?.app_requests_total_duration(\n {\n method,\n route,\n status_code,\n appId,\n databaseId,\n },\n duration\n )\n }\n\n /**\n * Start periodic push to VM-agent (`METRICS_PUSHGATEWAY_URL`). Interval defaults to `intervalSec` from config/env.\n * @param {number} [interval] Seconds between pushes; defaults to `this.intervalSec`\n * @param {() => void | Promise<void>} [customPushMetrics] Optional; replaces default push when provided\n * @returns {void}\n */\n startPush = (interval, customPushMetrics) => {\n if (this._webRedisHttpRecordingOnly) {\n return\n }\n if (!shouldRunMetricsPush(this)) {\n if (\n this.enabled &&\n !this._skippedPushWorkerLogged &&\n process.env.METRICS_SUPPRESS_SKIP_PUSH_LOG !== 'true'\n ) {\n console.warn(\n `${this.prefixLogs} Skipping VM-agent push on this worker. METRICS_PUSH_ALL_WORKERS=true restores per-worker push.`\n )\n this._skippedPushWorkerLogged = true\n }\n return\n }\n this._startPush(interval, customPushMetrics)\n }\n\n async pushMetrics() {\n if (this._webRedisHttpRecordingOnly) {\n return\n }\n if (\n this._httpRedisStore &&\n shouldRunMetricsPush(this) &&\n this.countersFunctions?.app_requests_total &&\n this.countersFunctions?.app_requests_total_duration\n ) {\n await this._httpRedisStore.flushToCounters(\n (labels, value) =>\n this.countersFunctions.app_requests_total(labels, value),\n (labels, value) =>\n this.countersFunctions.app_requests_total_duration(labels, value)\n )\n }\n // eslint-disable-next-line consistent-return\n return super.pushMetrics()\n }\n\n trackHttpRequestMiddleware = (req, res, next) => {\n if (!this.enabled || !this.httpMetricsEnabled || req.method === 'OPTIONS') {\n next()\n return\n }\n\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 req.params?.datasourceId ||\n req.body?.datasourceId ||\n req.query?.datasourceId ||\n ''\n\n this.trackHttpRequest({\n method: req.method,\n route,\n status_code: res.statusCode,\n appId,\n databaseId,\n duration: Date.now() - start,\n })\n })\n\n next()\n }\n}\n\nmodule.exports = { MetricsClient }\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"metricsClient.js","names":["fs","require","os","BaseMetricsClient","shouldRunMetricsPush","HttpMetricsRedisStore","isRedisPeerInstalled","isWebServingDynoContext","processType","dyno","process","env","DYNO","test","isMetricsExporterProcessType","MetricsClient","constructor","config","processTypeBeforeSuper","BUILD_DYNO_PROCESS_TYPE","redisUrl","httpMetricsRedisUrl","METRICS_HTTP_REDIS_URL","REDIS_URL","httpMetricsEnabled","undefined","METRICS_HTTP_ENABLED","httpMetricsRedisAggregation","Boolean","console","warn","isWebCtx","webRedisRecordingOnly","NODE_ENV","includeNodeDefaultMetrics","redisKeyProcessType","_httpRedisStore","appName","_webRedisHttpRecordingOnly","exportRuntimeGauges","wcParsed","parseInt","WEB_CONCURRENCY","_bootstrapWebConcurrency","Number","isFinite","_bootstrapHostCpuCount","cpus","length","defaultLabelsWithoutDynoId","app","process_type","_skippedPushWorkerLogged","_lastUsageMicros","_lastCheckTime","Date","now","_initDefaultMetrics","_logMetricsBootstrap","enabled","wc","httpMode","prefixLogs","dynoId","isWebRedisHttpRecordingOnly","createGauge","name","help","updateFn","getCpuUsagePercent","getAvailableCPUs","getContainerMemoryUsage","measureLag","getContainerMemoryLimit","uptime","registerHttpCounters","createCounter","labelNames","withDefaultLabelsWithoutDynoId","useLabelsWithoutDynoId","stat","readFileSync","match","currentUsage","deltaUsage","deltaTime","cpuMaxPath","existsSync","quotaStr","periodStr","trim","split","memoryUsage","rss","path","val","parsed","totalmem","Promise","resolve","start","setImmediate","trackHttpRequest","method","route","status_code","appId","databaseId","duration","record","countersFunctions","app_requests_total","app_requests_total_duration","startPush","interval","customPushMetrics","METRICS_SUPPRESS_SKIP_PUSH_LOG","_startPush","pushMetrics","flushToCounters","labels","value","trackHttpRequestMiddleware","req","res","next","on","params","body","query","datasourceId","statusCode","module","exports"],"sources":["../../src/metrics/metricsClient.js"],"sourcesContent":["const fs = require('fs')\nconst os = require('os')\nconst { BaseMetricsClient } = require('./baseMetricsClient')\nconst { shouldRunMetricsPush } = require('./shouldRunMetricsPush')\nconst {\n HttpMetricsRedisStore,\n isRedisPeerInstalled,\n} = require('./httpMetricsRedisStore')\n\n/**\n * Heroku-style: DYNO=web.1 → web serving; DYNO=metrics.1 → VM-agent exporter (Procfile `metrics:`).\n * Without DYNO (local Docker), falls back to BUILD_DYNO_PROCESS_TYPE === 'web'.\n */\nfunction isWebServingDynoContext(processType) {\n const dyno = process.env.DYNO || ''\n if (dyno) {\n return /^web\\./.test(dyno)\n }\n return processType === 'web'\n}\n\nfunction isMetricsExporterProcessType(processType) {\n const dyno = process.env.DYNO || ''\n if (dyno) {\n return /^metrics\\./.test(dyno)\n }\n return processType === 'metrics'\n}\n\n/**\n * MetricsClient handles Prometheus metrics collection and push.\n *\n * **Redis HTTP:** When `METRICS_HTTP_ENABLED` and a Redis URL exist, HTTP counts use Redis\n * (key segment from BUILD_APP_NAME + process type). Production **web.*** dynos only write Redis;\n * run Procfile **`metrics`** + **metrics-exporter.js** to drain and POST. Tests: `httpMetricsRedisAggregation: false`.\n */\nclass MetricsClient extends BaseMetricsClient {\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, metrics, etc.)\n * @param {boolean} [config.enabled] Enable metrics collection\n * @param {boolean} [config.httpMetricsEnabled] Enable HTTP request metrics (app_requests_total, app_requests_total_duration); defaults from METRICS_HTTP_ENABLED\n * @param {boolean} [config.logValues] Log metrics values to console\n * @param {string} [config.pushgatewayUrl] Push URL (VM-agent import endpoint)\n * @param {string} [config.pushgatewaySecret] Basic auth secret (Base64 user:password)\n * @param {number} [config.intervalSec] Interval in seconds for pushing metrics\n * @param {boolean} [config.removeOldMetrics] Enable to clear metrics by service name\n * @param {function} [config.startupValidation] Add to validate on start push\n * @param {boolean} [config.disablePushgateway] Disable pushing to VM-agent (use HTTP scraping instead)\n * @param {boolean} [config.includeNodeDefaultMetrics] Register prom-client default process metrics\n * @param {string} [config.httpMetricsRedisUrl] Overrides METRICS_HTTP_REDIS_URL / REDIS_URL for the HTTP Redis store\n * @param {boolean} [config.httpMetricsRedisAggregation] When unset, on if Redis + HTTP metrics; set false to force in-process HTTP counters only\n */\n constructor(config = {}) {\n const processTypeBeforeSuper =\n config.processType || process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined_build_dyno_type'\n\n const redisUrl =\n config.httpMetricsRedisUrl ||\n process.env.METRICS_HTTP_REDIS_URL ||\n process.env.REDIS_URL ||\n ''\n\n let httpMetricsEnabled\n if (config.httpMetricsEnabled !== undefined) {\n httpMetricsEnabled = config.httpMetricsEnabled\n } else if (process.env.METRICS_HTTP_ENABLED === 'true') {\n httpMetricsEnabled = true\n } else if (isMetricsExporterProcessType(processTypeBeforeSuper) && redisUrl) {\n // metrics: dyno must drain Redis HTTP keys; many stacks omit METRICS_HTTP_ENABLED here\n httpMetricsEnabled = true\n } else {\n httpMetricsEnabled = false\n }\n\n let httpMetricsRedisAggregation =\n Boolean(redisUrl) &&\n Boolean(httpMetricsEnabled) &&\n config.httpMetricsRedisAggregation !== false\n\n if (httpMetricsRedisAggregation && !isRedisPeerInstalled()) {\n console.warn(\n '[MetricsClient] METRICS_HTTP_ENABLED with REDIS_URL needs the peer package `redis` in your application (npm install redis@3). Falling back to in-process HTTP counters. @adalo/metrics does not bundle redis.'\n )\n httpMetricsRedisAggregation = false\n }\n\n const isWebCtx = isWebServingDynoContext(processTypeBeforeSuper)\n const webRedisRecordingOnly =\n Boolean(httpMetricsRedisAggregation) &&\n isWebCtx &&\n process.env.NODE_ENV === 'production'\n\n super({\n ...config,\n ...(webRedisRecordingOnly ? { includeNodeDefaultMetrics: false } : {}),\n })\n\n this.httpMetricsEnabled = httpMetricsEnabled\n this.httpMetricsRedisAggregation = httpMetricsRedisAggregation\n\n const redisKeyProcessType = isMetricsExporterProcessType(this.processType)\n ? 'web'\n : this.processType\n\n this._httpRedisStore =\n this.httpMetricsEnabled && this.httpMetricsRedisAggregation\n ? new HttpMetricsRedisStore({\n redisUrl,\n appName: this.appName,\n processType: redisKeyProcessType,\n })\n : null\n\n this._webRedisHttpRecordingOnly = Boolean(\n webRedisRecordingOnly && this._httpRedisStore\n )\n\n this.exportRuntimeGauges = !this._webRedisHttpRecordingOnly\n\n const wcParsed = parseInt(process.env.WEB_CONCURRENCY || '', 10)\n this._bootstrapWebConcurrency = Number.isFinite(wcParsed) ? wcParsed : 0\n this._bootstrapHostCpuCount = os.cpus().length\n\n if (this.httpMetricsRedisAggregation && redisUrl) {\n if (isMetricsExporterProcessType(this.processType)) {\n this.defaultLabelsWithoutDynoId = {\n app: this.appName,\n process_type: 'web',\n }\n } else if (!this._webRedisHttpRecordingOnly) {\n this.defaultLabelsWithoutDynoId = {\n app: this.appName,\n process_type: this.processType,\n }\n }\n }\n\n this._skippedPushWorkerLogged = false\n\n this._lastUsageMicros = 0\n this._lastCheckTime = Date.now()\n\n this._initDefaultMetrics()\n this._logMetricsBootstrap()\n }\n\n _logMetricsBootstrap = () => {\n if (!this.enabled) {\n return\n }\n const wc = process.env.WEB_CONCURRENCY || ''\n const httpMode = !this.httpMetricsEnabled\n ? 'off'\n : this._httpRedisStore\n ? 'redis'\n : 'local_counters'\n console.warn(\n `${this.prefixLogs} metrics bootstrap WEB_CONCURRENCY=${wc || '(unset)'} host_cpus=${this._bootstrapHostCpuCount} dyno_id=${this.dynoId} process_type=${this.processType} scheduling_id=${process.env.DYNO || 'n/a'} http_metrics=${httpMode} redis_http=${this.httpMetricsRedisAggregation} web_redis_only=${this._webRedisHttpRecordingOnly}`\n )\n }\n\n get isWebRedisHttpRecordingOnly() {\n return Boolean(this._webRedisHttpRecordingOnly)\n }\n\n _initDefaultMetrics = () => {\n if (this.exportRuntimeGauges) {\n this.createGauge({\n name: 'app_process_cpu_usage_percent',\n help: 'Current CPU usage of the Node.js process in percent',\n updateFn: this.getCpuUsagePercent,\n })\n\n this.createGauge({\n name: 'app_available_cpu_count',\n help: 'How many CPU cores are available to this process',\n updateFn: this.getAvailableCPUs,\n })\n\n this.createGauge({\n name: 'app_container_memory_usage_bytes',\n help: 'Current container RAM usage from cgroup',\n updateFn: this.getContainerMemoryUsage,\n })\n\n this.createGauge({\n name: 'app_event_loop_lag_ms',\n help: 'Estimated event loop lag in milliseconds',\n updateFn: this.measureLag,\n })\n\n this.createGauge({\n name: 'app_container_memory_limit_bytes',\n help: 'Max RAM available to container from cgroup (memory.max)',\n updateFn: this.getContainerMemoryLimit,\n })\n\n this.createGauge({\n name: 'app_uptime_seconds',\n help: 'How long the process has been running',\n updateFn: process.uptime,\n })\n\n this.createGauge({\n name: 'app_bootstrap_web_concurrency',\n help: 'WEB_CONCURRENCY at process start (diagnostic; 0 if unset/invalid)',\n updateFn: () => this._bootstrapWebConcurrency,\n })\n\n this.createGauge({\n name: 'app_bootstrap_host_cpu_count',\n help: 'os.cpus().length at process start (diagnostic)',\n updateFn: () => this._bootstrapHostCpuCount,\n })\n }\n\n const registerHttpCounters =\n this.httpMetricsEnabled && !this._webRedisHttpRecordingOnly\n\n if (registerHttpCounters) {\n this.createCounter({\n name: 'app_requests_total',\n help: 'Total number of HTTP requests',\n labelNames: this.withDefaultLabelsWithoutDynoId([\n 'method',\n 'route',\n 'appId',\n 'databaseId',\n 'status_code',\n ]),\n useLabelsWithoutDynoId: true,\n })\n\n this.createCounter({\n name: 'app_requests_total_duration',\n help: 'Total duration of HTTP requests in milliseconds',\n labelNames: this.withDefaultLabelsWithoutDynoId([\n 'method',\n 'route',\n 'appId',\n 'databaseId',\n 'status_code',\n ]),\n useLabelsWithoutDynoId: true,\n })\n }\n }\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 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 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 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 measureLag() {\n return new Promise(resolve => {\n const start = Date.now()\n setImmediate(() => resolve(Date.now() - start))\n })\n }\n\n trackHttpRequest({\n method,\n route,\n status_code,\n appId = '',\n databaseId = '',\n duration,\n }) {\n if (!this.httpMetricsEnabled) return\n\n if (this._httpRedisStore) {\n this._httpRedisStore.record(\n method,\n route,\n status_code,\n appId,\n databaseId,\n duration\n )\n return\n }\n\n this.countersFunctions?.app_requests_total({\n method,\n route,\n status_code,\n appId,\n databaseId,\n })\n this.countersFunctions?.app_requests_total_duration(\n {\n method,\n route,\n status_code,\n appId,\n databaseId,\n },\n duration\n )\n }\n\n /**\n * Start periodic push to VM-agent (`METRICS_PUSHGATEWAY_URL`). Interval defaults to `intervalSec` from config/env.\n * @param {number} [interval] Seconds between pushes; defaults to `this.intervalSec`\n * @param {() => void | Promise<void>} [customPushMetrics] Optional; replaces default push when provided\n * @returns {void}\n */\n startPush = (interval, customPushMetrics) => {\n if (this._webRedisHttpRecordingOnly) {\n return\n }\n if (!shouldRunMetricsPush(this)) {\n if (\n this.enabled &&\n !this._skippedPushWorkerLogged &&\n process.env.METRICS_SUPPRESS_SKIP_PUSH_LOG !== 'true'\n ) {\n console.warn(\n `${this.prefixLogs} Skipping VM-agent push on this worker. METRICS_PUSH_ALL_WORKERS=true restores per-worker push.`\n )\n this._skippedPushWorkerLogged = true\n }\n return\n }\n this._startPush(interval, customPushMetrics)\n }\n\n async pushMetrics() {\n if (this._webRedisHttpRecordingOnly) {\n return\n }\n if (\n this._httpRedisStore &&\n shouldRunMetricsPush(this) &&\n this.countersFunctions?.app_requests_total &&\n this.countersFunctions?.app_requests_total_duration\n ) {\n await this._httpRedisStore.flushToCounters(\n (labels, value) =>\n this.countersFunctions.app_requests_total(labels, value),\n (labels, value) =>\n this.countersFunctions.app_requests_total_duration(labels, value)\n )\n }\n // eslint-disable-next-line consistent-return\n return super.pushMetrics()\n }\n\n trackHttpRequestMiddleware = (req, res, next) => {\n if (!this.enabled || !this.httpMetricsEnabled || req.method === 'OPTIONS') {\n next()\n return\n }\n\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 req.params?.datasourceId ||\n req.body?.datasourceId ||\n req.query?.datasourceId ||\n ''\n\n this.trackHttpRequest({\n method: req.method,\n route,\n status_code: res.statusCode,\n appId,\n databaseId,\n duration: Date.now() - start,\n })\n })\n\n next()\n }\n}\n\nmodule.exports = { MetricsClient }\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -57,17 +57,24 @@ class MetricsClient extends BaseMetricsClient {
|
|
|
57
57
|
const processTypeBeforeSuper =
|
|
58
58
|
config.processType || process.env.BUILD_DYNO_PROCESS_TYPE || 'undefined_build_dyno_type'
|
|
59
59
|
|
|
60
|
-
const httpMetricsEnabled =
|
|
61
|
-
config.httpMetricsEnabled ??
|
|
62
|
-
process.env.METRICS_HTTP_ENABLED === 'true' ??
|
|
63
|
-
false
|
|
64
|
-
|
|
65
60
|
const redisUrl =
|
|
66
61
|
config.httpMetricsRedisUrl ||
|
|
67
62
|
process.env.METRICS_HTTP_REDIS_URL ||
|
|
68
63
|
process.env.REDIS_URL ||
|
|
69
64
|
''
|
|
70
65
|
|
|
66
|
+
let httpMetricsEnabled
|
|
67
|
+
if (config.httpMetricsEnabled !== undefined) {
|
|
68
|
+
httpMetricsEnabled = config.httpMetricsEnabled
|
|
69
|
+
} else if (process.env.METRICS_HTTP_ENABLED === 'true') {
|
|
70
|
+
httpMetricsEnabled = true
|
|
71
|
+
} else if (isMetricsExporterProcessType(processTypeBeforeSuper) && redisUrl) {
|
|
72
|
+
// metrics: dyno must drain Redis HTTP keys; many stacks omit METRICS_HTTP_ENABLED here
|
|
73
|
+
httpMetricsEnabled = true
|
|
74
|
+
} else {
|
|
75
|
+
httpMetricsEnabled = false
|
|
76
|
+
}
|
|
77
|
+
|
|
71
78
|
let httpMetricsRedisAggregation =
|
|
72
79
|
Boolean(redisUrl) &&
|
|
73
80
|
Boolean(httpMetricsEnabled) &&
|
|
@@ -145,8 +152,13 @@ class MetricsClient extends BaseMetricsClient {
|
|
|
145
152
|
return
|
|
146
153
|
}
|
|
147
154
|
const wc = process.env.WEB_CONCURRENCY || ''
|
|
155
|
+
const httpMode = !this.httpMetricsEnabled
|
|
156
|
+
? 'off'
|
|
157
|
+
: this._httpRedisStore
|
|
158
|
+
? 'redis'
|
|
159
|
+
: 'local_counters'
|
|
148
160
|
console.warn(
|
|
149
|
-
`${this.prefixLogs} metrics bootstrap WEB_CONCURRENCY=${wc || '(unset)'} host_cpus=${this._bootstrapHostCpuCount}
|
|
161
|
+
`${this.prefixLogs} metrics bootstrap WEB_CONCURRENCY=${wc || '(unset)'} host_cpus=${this._bootstrapHostCpuCount} dyno_id=${this.dynoId} process_type=${this.processType} scheduling_id=${process.env.DYNO || 'n/a'} http_metrics=${httpMode} redis_http=${this.httpMetricsRedisAggregation} web_redis_only=${this._webRedisHttpRecordingOnly}`
|
|
150
162
|
)
|
|
151
163
|
}
|
|
152
164
|
|