diff --git a/app/api/server/api.js b/app/api/server/api.js index eab220650d6..8c5f77b7fd0 100644 --- a/app/api/server/api.js +++ b/app/api/server/api.js @@ -21,6 +21,7 @@ export const defaultRateLimiterOptions = { numRequestsAllowed: settings.get('API_Enable_Rate_Limiter_Limit_Calls_Default'), intervalTimeInMS: settings.get('API_Enable_Rate_Limiter_Limit_Time_Default'), }; +let prometheusAPIUserAgent = false; export let API = {}; @@ -320,8 +321,8 @@ export class APIClass extends Restivus { const rocketchatRestApiEnd = metrics.rocketchatRestApi.startTimer({ method, version, - user_agent: this.request.headers['user-agent'], - entrypoint: route, + ...prometheusAPIUserAgent && { user_agent: this.request.headers['user-agent'] }, + entrypoint: route.startsWith('method.call') ? decodeURIComponent(this.request._parsedUrl.pathname.slice(8)) : route, }); logger.debug(`${ this.request.method.toUpperCase() }: ${ this.request.url }`); @@ -695,3 +696,7 @@ settings.get('API_Enable_Rate_Limiter_Limit_Calls_Default', (key, value) => { defaultRateLimiterOptions.numRequestsAllowed = value; API.v1.reloadRoutesToRefreshRateLimiter(); }); + +settings.get('Prometheus_API_User_Agent', (key, value) => { + prometheusAPIUserAgent = value; +}); diff --git a/app/lib/server/startup/settings.js b/app/lib/server/startup/settings.js index 7f42f30ee2d..f395501d02e 100644 --- a/app/lib/server/startup/settings.js +++ b/app/lib/server/startup/settings.js @@ -1460,6 +1460,16 @@ settings.addGroup('Logs', function() { type: 'string', i18nLabel: 'Port', }); + this.add('Prometheus_Reset_Interval', 0, { + type: 'int', + }); + this.add('Prometheus_Garbage_Collector', false, { + type: 'boolean', + alert: 'Prometheus_Garbage_Collector_Alert', + }); + this.add('Prometheus_API_User_Agent', false, { + type: 'boolean', + }); }); }); diff --git a/app/metrics/server/lib/metrics.js b/app/metrics/server/lib/metrics.js index ecabb6c67f7..d5f7b395309 100644 --- a/app/metrics/server/lib/metrics.js +++ b/app/metrics/server/lib/metrics.js @@ -3,6 +3,7 @@ import http from 'http'; import client from 'prom-client'; import connect from 'connect'; import _ from 'underscore'; +import gcStats from 'prometheus-gc-stats'; import { Meteor } from 'meteor/meteor'; import { Info, getOplogInfo } from '../../../utils/server'; @@ -11,45 +12,55 @@ import { settings } from '../../../settings'; import { Statistics } from '../../../models'; import { oplogEvents } from '../../../models/server/oplogEvents'; -client.collectDefaultMetrics(); - export const metrics = {}; +const percentiles = [0.01, 0.1, 0.9, 0.99]; + +// Metrics +metrics.metricsRequests = new client.Counter({ name: 'rocketchat_metrics_requests', labelNames: ['notification_type'], help: 'cumulated number of calls to the metrics endpoint' }); +metrics.metricsSize = new client.Gauge({ name: 'rocketchat_metrics_size', help: 'size of the metrics response in chars' }); + +metrics.info = new client.Gauge({ name: 'rocketchat_info', labelNames: ['version', 'unique_id', 'site_url'], help: 'Rocket.Chat info' }); metrics.meteorMethods = new client.Summary({ name: 'rocketchat_meteor_methods', help: 'summary of meteor methods count and time', labelNames: ['method', 'has_connection', 'has_user'], + percentiles, }); metrics.rocketchatCallbacks = new client.Summary({ name: 'rocketchat_callbacks', help: 'summary of rocketchat callbacks count and time', labelNames: ['hook', 'callback'], + percentiles, }); metrics.rocketchatHooks = new client.Summary({ name: 'rocketchat_hooks', help: 'summary of rocketchat hooks count and time', labelNames: ['hook', 'callbacks_length'], + percentiles, }); metrics.rocketchatRestApi = new client.Summary({ name: 'rocketchat_rest_api', help: 'summary of rocketchat rest api count and time', labelNames: ['method', 'entrypoint', 'user_agent', 'status', 'version'], + percentiles, }); metrics.meteorSubscriptions = new client.Summary({ name: 'rocketchat_meteor_subscriptions', help: 'summary of meteor subscriptions count and time', labelNames: ['subscription'], + percentiles, }); metrics.messagesSent = new client.Counter({ name: 'rocketchat_message_sent', help: 'cumulated number of messages sent' }); metrics.notificationsSent = new client.Counter({ name: 'rocketchat_notification_sent', labelNames: ['notification_type'], help: 'cumulated number of notifications sent' }); metrics.ddpSessions = new client.Gauge({ name: 'rocketchat_ddp_sessions_count', help: 'number of open ddp sessions' }); -metrics.ddpAthenticatedSessions = new client.Gauge({ name: 'rocketchat_ddp_sessions_auth', help: 'number of authenticated open ddp sessions' }); +metrics.ddpAuthenticatedSessions = new client.Gauge({ name: 'rocketchat_ddp_sessions_auth', help: 'number of authenticated open ddp sessions' }); metrics.ddpConnectedUsers = new client.Gauge({ name: 'rocketchat_ddp_connected_users', help: 'number of unique connected users' }); metrics.ddpRateLimitExceeded = new client.Counter({ name: 'rocketchat_ddp_rate_limit_exceeded', labelNames: ['limit_name', 'user_id', 'client_address', 'type', 'name', 'connection_id'], help: 'number of times a ddp rate limiter was exceeded' }); @@ -87,57 +98,52 @@ metrics.totalDirectMessages = new client.Gauge({ name: 'rocketchat_direct_messag metrics.totalLivechatMessages = new client.Gauge({ name: 'rocketchat_livechat_messages_total', help: 'total of messages in livechat rooms' }); const setPrometheusData = async () => { - client.register.setDefaultLabels({ - uniqueId: settings.get('uniqueID'), - siteUrl: settings.get('Site_Url'), - }); - const date = new Date(); - client.register.setDefaultLabels({ + metrics.info.set({ + version: Info.version, unique_id: settings.get('uniqueID'), site_url: settings.get('Site_Url'), - version: Info.version, - }); + }, 1); const sessions = Array.from(Meteor.server.sessions.values()); const authenticatedSessions = sessions.filter((s) => s.userId); - metrics.ddpSessions.set(Meteor.server.sessions.size, date); - metrics.ddpAthenticatedSessions.set(authenticatedSessions.length, date); - metrics.ddpConnectedUsers.set(_.unique(authenticatedSessions.map((s) => s.userId)).length, date); + metrics.ddpSessions.set(Meteor.server.sessions.size); + metrics.ddpAuthenticatedSessions.set(authenticatedSessions.length); + metrics.ddpConnectedUsers.set(_.unique(authenticatedSessions.map((s) => s.userId)).length); const statistics = Statistics.findLast(); if (!statistics) { return; } - metrics.version.set({ version: statistics.version }, 1, date); - metrics.migration.set(Migrations._getControl().version, date); - metrics.instanceCount.set(statistics.instanceCount, date); - metrics.oplogEnabled.set({ enabled: statistics.oplogEnabled }, 1, date); + metrics.version.set({ version: statistics.version }, 1); + metrics.migration.set(Migrations._getControl().version); + metrics.instanceCount.set(statistics.instanceCount); + metrics.oplogEnabled.set({ enabled: statistics.oplogEnabled }, 1); // User statistics - metrics.totalUsers.set(statistics.totalUsers, date); - metrics.activeUsers.set(statistics.activeUsers, date); - metrics.nonActiveUsers.set(statistics.nonActiveUsers, date); - metrics.onlineUsers.set(statistics.onlineUsers, date); - metrics.awayUsers.set(statistics.awayUsers, date); - metrics.offlineUsers.set(statistics.offlineUsers, date); + metrics.totalUsers.set(statistics.totalUsers); + metrics.activeUsers.set(statistics.activeUsers); + metrics.nonActiveUsers.set(statistics.nonActiveUsers); + metrics.onlineUsers.set(statistics.onlineUsers); + metrics.awayUsers.set(statistics.awayUsers); + metrics.offlineUsers.set(statistics.offlineUsers); // Room statistics - metrics.totalRooms.set(statistics.totalRooms, date); - metrics.totalChannels.set(statistics.totalChannels, date); - metrics.totalPrivateGroups.set(statistics.totalPrivateGroups, date); - metrics.totalDirect.set(statistics.totalDirect, date); - metrics.totalLivechat.set(statistics.totalLivechat, date); + metrics.totalRooms.set(statistics.totalRooms); + metrics.totalChannels.set(statistics.totalChannels); + metrics.totalPrivateGroups.set(statistics.totalPrivateGroups); + metrics.totalDirect.set(statistics.totalDirect); + metrics.totalLivechat.set(statistics.totalLivechat); // Message statistics - metrics.totalMessages.set(statistics.totalMessages, date); - metrics.totalChannelMessages.set(statistics.totalChannelMessages, date); - metrics.totalPrivateGroupMessages.set(statistics.totalPrivateGroupMessages, date); - metrics.totalDirectMessages.set(statistics.totalDirectMessages, date); - metrics.totalLivechatMessages.set(statistics.totalLivechatMessages, date); + metrics.totalMessages.set(statistics.totalMessages); + metrics.totalChannelMessages.set(statistics.totalChannelMessages); + metrics.totalPrivateGroupMessages.set(statistics.totalPrivateGroupMessages); + metrics.totalDirectMessages.set(statistics.totalDirectMessages); + metrics.totalLivechatMessages.set(statistics.totalLivechatMessages); const oplogQueue = getOplogInfo().mongo._oplogHandle?._entryQueue?.length || 0; - metrics.oplogQueue.set(oplogQueue, date); + metrics.oplogQueue.set(oplogQueue); }; const app = connect(); @@ -147,7 +153,12 @@ const app = connect(); app.use('/metrics', (req, res) => { res.setHeader('Content-Type', 'text/plain'); - res.end(client.register.metrics()); + const data = client.register.metrics(); + + metrics.metricsRequests.inc(); + metrics.metricsSize.set(data.length); + + res.end(data); }); app.use('/', (req, res) => { @@ -175,35 +186,79 @@ const oplogMetric = ({ collection, op }) => { }; let timer; -let wasEnabled = false; +let resetTimer; +let defaultMetricsInitiated = false; +let gcStatsInitiated = false; +const was = { + enabled: false, + port: 9458, + resetInterval: 0, + collectGC: false, +}; const updatePrometheusConfig = async () => { - const port = process.env.PROMETHEUS_PORT || settings.get('Prometheus_Port'); - const enabled = Boolean(port && settings.get('Prometheus_Enabled')); - - if (wasEnabled === enabled) { + const is = { + port: process.env.PROMETHEUS_PORT || settings.get('Prometheus_Port'), + enabled: settings.get('Prometheus_Enabled'), + resetInterval: settings.get('Prometheus_Reset_Interval'), + collectGC: settings.get('Prometheus_Garbage_Collector'), + }; + + if (Object.values(is).some((s) => s == null)) { return; } - wasEnabled = enabled; + if (Object.entries(is).every(([k, v]) => v === was[k])) { + return; + } - if (!enabled) { - server.close(); - Meteor.clearInterval(timer); - oplogEvents.removeListener('record', oplogMetric); + if (!is.enabled) { + if (was.enabled) { + console.log('Disabling Prometheus'); + server.close(); + Meteor.clearInterval(timer); + oplogEvents.removeListener('record', oplogMetric); + } + Object.assign(was, is); return; } - server.listen({ - port, - host: process.env.BIND_IP || '0.0.0.0', - }); + console.log('Configuring Prometheus', is); + + if (!was.enabled) { + server.listen({ + port: is.port, + host: process.env.BIND_IP || '0.0.0.0', + }); - timer = Meteor.setInterval(setPrometheusData, 5000); + timer = Meteor.setInterval(setPrometheusData, 5000); + oplogEvents.on('record', oplogMetric); + } + + Meteor.clearInterval(resetTimer); + if (is.resetInterval) { + resetTimer = Meteor.setInterval(() => { + client.register.getMetricsAsArray().forEach((metric) => { metric.hashMap = {}; }); + }, is.resetInterval); + } + + // Prevent exceptions on calling those methods twice since + // it's not possible to stop them to be able to restart + try { + if (defaultMetricsInitiated === false) { + defaultMetricsInitiated = true; + client.collectDefaultMetrics(); + } + if (is.collectGC && gcStatsInitiated === false) { + gcStatsInitiated = true; + gcStats()(); + } + } catch (error) { + console.error(error); + } - oplogEvents.on('record', oplogMetric); + Object.assign(was, is); }; Meteor.startup(async () => { - settings.get('Prometheus_Enabled', updatePrometheusConfig); - settings.get('Prometheus_Port', updatePrometheusConfig); + settings.get(/^Prometheus_.+/, updatePrometheusConfig); }); diff --git a/package-lock.json b/package-lock.json index e7b92f87994..54b8e0fd8da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2925,17 +2925,21 @@ }, "@rocket.chat/fuselage-ui-kit": { "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-ui-kit/-/fuselage-ui-kit-0.7.1.tgz", + "integrity": "sha512-3OhOJ2yA1i/npYK9BeFFLuPGh9zBXCVS9PfWpN+Mc5dlCvB3CCduYExiIfho8+JZW83IXwIm9HlYsLyqMhpBpg==", "requires": { "@rocket.chat/ui-kit": "^0.7.1" }, "dependencies": { "@babel/preset-react": { - "version": "7.9.4" + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.4.tgz", + "integrity": "sha512-AxylVB3FXeOTQXNXyiuAQJSvss62FEotbX2Pzx3K/7c+MKJMdSg6Ose6QYllkdCFA8EInCJVw7M/o5QbLuA4ZQ==" }, "@rocket.chat/ui-kit": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@rocket.chat/ui-kit/-/ui-kit-0.7.0.tgz", - "integrity": "sha512-qsBRQlUJhLga30qosHmiVsdLLBi2vjqBhAfKvYPAT0Qe5FzsuTRn6vtOnYk16A4mZ8hV8gWNDleuvG46vOk+LA==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@rocket.chat/ui-kit/-/ui-kit-0.7.1.tgz", + "integrity": "sha512-CUpJt35zq56n4lBwWs17PRa+GGY+NKILv2ydjlL+dQNbtb9peEEzTVmglLRXUJhIwNKndSAr0eqoeTkRIsWL6A==" } } }, @@ -16132,6 +16136,493 @@ } } }, + "gc-stats": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gc-stats/-/gc-stats-1.4.0.tgz", + "integrity": "sha512-4FcCj9e8j8rCjvLkqRpGZBLgTC/xr9XEf5By3x77cDucWWB3pJK6FEwXZCTCbb4z8xdaOoi4owBNrvn3ciDdxA==", + "optional": true, + "requires": { + "nan": "^2.13.2", + "node-pre-gyp": "^0.13.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "needle": { + "version": "2.3.1", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.13.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, "gcp-metadata": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz", @@ -22613,6 +23104,11 @@ "wordwrap": "~0.0.2" } }, + "optional": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/optional/-/optional-0.1.4.tgz", + "integrity": "sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw==" + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -24116,13 +24612,22 @@ } }, "prom-client": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.2.0.tgz", - "integrity": "sha512-4gUAq/GR5C8q5eWxOa7tA60AtmkMpbyBd/2btCayvd3h/7HzS0p/kESKRwggJgbFrfdhTCBpOwPAwKiI01Q0VQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-12.0.0.tgz", + "integrity": "sha512-JbzzHnw0VDwCvoqf8y1WDtq4wSBAbthMB1pcVI/0lzdqHGJI3KBJDXle70XK+c7Iv93Gihqo0a5LlOn+g8+DrQ==", "requires": { "tdigest": "^0.1.1" } }, + "prometheus-gc-stats": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/prometheus-gc-stats/-/prometheus-gc-stats-0.6.2.tgz", + "integrity": "sha512-ABSVHkAuYrMLj1WHmlLfS0hu9Vc2ELKuecwiMWPNQom+ZNiAdcILTn5yGK7sZg2ttoWc2u++W5NjdJ3IjdYJZw==", + "requires": { + "gc-stats": "^1.2.1", + "optional": "^0.1.3" + } + }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", diff --git a/package.json b/package.json index 4b4b4763b78..adfdfa35d76 100644 --- a/package.json +++ b/package.json @@ -206,7 +206,8 @@ "pdfjs-dist": "^2.0.943", "photoswipe": "^4.1.3", "poplib": "^0.1.7", - "prom-client": "^11.2.0", + "prom-client": "^12.0.0", + "prometheus-gc-stats": "^0.6.2", "querystring": "^0.2.0", "queue-fifo": "^0.2.5", "react": "^16.8.6", diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index a7312db9ed0..04aa250198e 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -2685,6 +2685,10 @@ "Profile_picture": "Profile Picture", "Profile_saved_successfully": "Profile saved successfully", "Prometheus": "Prometheus", + "Prometheus_Reset_Interval": "Reset Interval (ms)", + "Prometheus_Garbage_Collector": "Collect NodeJS GC", + "Prometheus_Garbage_Collector_Alert": "Restart required to deactivate", + "Prometheus_API_User_Agent": "API: Track User Agent", "Protocol": "Protocol", "Prune": "Prune", "Prune_finished": "Prune finished",