2021-08-20 21:09:34 +08:00
|
|
|
import {
|
2021-10-07 02:55:19 +08:00
|
|
|
register,
|
|
|
|
collectDefaultMetrics,
|
2021-08-20 21:09:34 +08:00
|
|
|
} from 'prom-client';
|
2021-10-07 02:55:19 +08:00
|
|
|
|
|
|
|
import Logger from '../logger';
|
|
|
|
const LOG_PREFIX = '[prom-scrape-agt]';
|
|
|
|
|
2021-08-20 21:09:34 +08:00
|
|
|
class PrometheusScrapeAgent {
|
2021-11-06 00:31:23 +08:00
|
|
|
constructor(options) {
|
2021-10-07 02:55:19 +08:00
|
|
|
this.metrics = {};
|
|
|
|
this.started = false;
|
|
|
|
|
|
|
|
this.path = options.path || '/metrics';
|
|
|
|
this.collectDefaultMetrics = options.collectDefaultMetrics || false;
|
|
|
|
this.metricsPrefix = options.prefix || '';
|
|
|
|
this.collectionTimeout = options.collectionTimeout || 10000;
|
2021-11-06 00:31:23 +08:00
|
|
|
this.roleAndInstanceLabels =
|
|
|
|
options.role
|
|
|
|
? { role: options.role, instanceId: options.instanceId }
|
|
|
|
: {};
|
2021-10-07 02:55:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-06 00:31:23 +08:00
|
|
|
start() {
|
2021-10-07 02:55:19 +08:00
|
|
|
if (this.collectDefaultMetrics) collectDefaultMetrics({
|
|
|
|
prefix: this.metricsPrefix,
|
|
|
|
timeout: this.collectionTimeout,
|
2021-11-06 00:31:23 +08:00
|
|
|
labels: this.roleAndInstanceLabels,
|
|
|
|
});
|
|
|
|
|
|
|
|
WebApp.connectHandlers.use(this.path, (req, res) => {
|
|
|
|
return this.collect(res);
|
2021-10-07 02:55:19 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
this.started = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
injectMetrics(metricsDictionary) {
|
|
|
|
this.metrics = { ...this.metrics, ...metricsDictionary }
|
|
|
|
}
|
|
|
|
|
|
|
|
increment(metricName, labelsObject) {
|
|
|
|
if (!this.started) return;
|
|
|
|
|
|
|
|
const metric = this.metrics[metricName];
|
|
|
|
if (metric) {
|
2021-11-06 00:31:23 +08:00
|
|
|
labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels };
|
2021-10-07 02:55:19 +08:00
|
|
|
metric.inc(labelsObject)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
decrement(metricName, labelsObject) {
|
|
|
|
if (!this.started) return;
|
|
|
|
|
|
|
|
const metric = this.metrics[metricName];
|
|
|
|
if (metric) {
|
2021-11-06 00:31:23 +08:00
|
|
|
labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels };
|
2021-10-07 02:55:19 +08:00
|
|
|
metric.dec(labelsObject)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set(metricName, value, labelsObject) {
|
|
|
|
if (!this.started) return;
|
|
|
|
|
|
|
|
const metric = this.metrics[metricName];
|
|
|
|
if (metric) {
|
2021-11-06 00:31:23 +08:00
|
|
|
labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels };
|
2021-10-07 02:55:19 +08:00
|
|
|
metric.set(labelsObject, value)
|
|
|
|
}
|
|
|
|
}
|
2021-09-25 03:20:37 +08:00
|
|
|
|
|
|
|
observe(metricName, value, labelsObject) {
|
|
|
|
if (!this.started) return;
|
|
|
|
|
|
|
|
const metric = this.metrics[metricName];
|
|
|
|
if (metric) {
|
|
|
|
labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels };
|
|
|
|
metric.observe(labelsObject, value)
|
|
|
|
}
|
|
|
|
}
|
2021-08-20 21:09:34 +08:00
|
|
|
}
|
|
|
|
|
2021-11-06 00:31:23 +08:00
|
|
|
export default PrometheusScrapeAgent;
|