feat(html5-server): add prometheus default instrumentation

Adds prometheus client to collect html5 server metrics.
Only default Node.js metrics in this initial version.

Enable via configs in private.app.prometheus
This commit is contained in:
germanocaumo 2021-10-06 18:55:19 +00:00
parent 585c263129
commit a0580431e0
6 changed files with 141 additions and 0 deletions

View File

@ -10,6 +10,7 @@ import Logger from './logger';
import Redis from './redis'; import Redis from './redis';
import setMinBrowserVersions from './minBrowserVersion'; import setMinBrowserVersions from './minBrowserVersion';
import MCSPrometheusAgent from './prom-metrics/index.js'
let guestWaitHtml = ''; let guestWaitHtml = '';

View File

@ -0,0 +1,29 @@
const Agent = require('./promAgent.js');
const METRICS_PREFIX = "html5_"
const {
enabled: METRICS_ENABLED,
host: METRICS_HOST,
port: METRICS_PORT,
path: METRICS_PATH,
collectDefaultMetrics: COLLECT_DEFAULT_METRICS,
} = Meteor.settings.private.prometheus
? Meteor.settings.private.prometheus
: { enabled: false };
const MCSPrometheusAgent = new Agent(METRICS_HOST, METRICS_PORT, {
path: METRICS_PATH,
prefix: METRICS_PREFIX,
collectDefaultMetrics: COLLECT_DEFAULT_METRICS,
});
if (METRICS_ENABLED) {
MCSPrometheusAgent.start();
}
module.exports = {
METRICS_PREFIX,
Agent,
MCSPrometheusAgent,
};

View File

@ -0,0 +1,90 @@
const {
register,
collectDefaultMetrics,
} = require('prom-client');
const HTTPServer = require('http')
import Logger from '../logger';
const LOG_PREFIX = '[prom-scrape-agt]';
module.exports = class PrometheusScrapeAgent {
constructor(host, port, options) {
this.host = host;
this.port = port;
this.metrics = {};
this.started = false;
this.path = options.path || '/metrics';
this.collectDefaultMetrics = options.collectDefaultMetrics || false;
this.metricsPrefix = options.prefix || '';
this.collectionTimeout = options.collectionTimeout || 10000;
}
async collect(response) {
try {
response.writeHead(200, { 'Content-Type': register.contentType });
const content = await register.metrics();
response.end(content);
Logger.debug(`${LOG_PREFIX} Collected prometheus metrics:\n${content}`);
} catch (error) {
response.writeHead(500)
response.end(error.message);
Logger.error(`${LOG_PREFIX} Collecting prometheus metrics: ${error.message}`);
}
}
getMetricsHandler(request, response) {
switch (request.method) {
case 'GET':
if (request.url === this.path) return this.collect(response);
response.writeHead(404).end();
break;
default:
response.writeHead(501)
response.end();
break;
}
}
start(requestHandler = this.getMetricsHandler.bind(this)) {
if (this.collectDefaultMetrics) collectDefaultMetrics({
prefix: this.metricsPrefix,
timeout: this.collectionTimeout,
});
this.metricsServer = HTTPServer.createServer(requestHandler);
this.metricsServer.listen(this.port, this.host);
this.started = true;
};
injectMetrics(metricsDictionary) {
this.metrics = { ...this.metrics, ...metricsDictionary }
}
increment(metricName, labelsObject) {
if (!this.started) return;
const metric = this.metrics[metricName];
if (metric) {
metric.inc(labelsObject)
}
}
decrement(metricName, labelsObject) {
if (!this.started) return;
const metric = this.metrics[metricName];
if (metric) {
metric.dec(labelsObject)
}
}
set(metricName, value, labelsObject) {
if (!this.started) return;
const metric = this.metrics[metricName];
if (metric) {
metric.set(labelsObject, value)
}
}
}

View File

@ -10001,6 +10001,14 @@
"sisteransi": "^1.0.5" "sisteransi": "^1.0.5"
} }
}, },
"prom-client": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.2.0.tgz",
"integrity": "sha512-wGr5mlNNdRNzEhRYXgboUU2LxHWIojxscJKmtG3R8f4/KiWqyYgXTLHs0+Ted7tG3zFT7pgHJbtomzZ1L0ARaQ==",
"requires": {
"tdigest": "^0.1.1"
}
},
"prop-types": { "prop-types": {
"version": "15.7.2", "version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",

View File

@ -51,6 +51,7 @@
"node-sass": "^6.0.1", "node-sass": "^6.0.1",
"postcss-nested": "^5.0.5", "postcss-nested": "^5.0.5",
"probe-image-size": "^4.1.1", "probe-image-size": "^4.1.1",
"prom-client": "^13.2.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"re-resizable": "^4.11.0", "re-resizable": "^4.11.0",
"react": "^16.14.0", "react": "^16.14.0",

View File

@ -711,3 +711,15 @@ private:
version: 10 version: 10
- browser: YandexBrowser - browser: YandexBrowser
version: 19 version: 19
# Direct Prometheus instrumentation.
# EXPERIMENTAL, so disabled by default.
prometheus:
enabled: false
# Scrape route host
host: localhost
# Scrape route port
port: 8080
# Metrics endpoint path
path: '/metrics'
# Whether default metrics for Node.js processes should be exported
collectDefaultMetrics: false