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:
parent
585c263129
commit
a0580431e0
@ -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 = '';
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
};
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
bigbluebutton-html5/package-lock.json
generated
8
bigbluebutton-html5/package-lock.json
generated
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user