@mdf.js/service-registry
Version:
MMS - API - Service Registry
161 lines • 6.11 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetricsFacade = void 0;
const tslib_1 = require("tslib");
/**
* Copyright 2024 Mytra Control S.L. All rights reserved.
*
* Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
* or at https://opensource.org/licenses/MIT.
*/
const core_1 = require("@mdf.js/core");
const logger_1 = require("@mdf.js/logger");
const events_1 = tslib_1.__importDefault(require("events"));
const prom_client_1 = require("prom-client");
const Aggregator_1 = require("./Aggregator");
const Router_1 = require("./Router");
const types_1 = require("./types");
/**
* MetricsFacade class serves as a facade to simplify metrics management across all services
* in an application. It leverages the prom-client library for metrics management and the express
* library to expose these metrics via an HTTP endpoint.
*
* It accommodates working in cluster environments by optionally creating a new AggregatorRegistry
* to hold metrics from all worker nodes, in addition to a separate registry for
* application-specific metrics and the default prom-client registry. Thus, it can manage up to
* three different registries:
*
* 1. Default prom-client registry for default metrics.
* 2. Application-specific metrics registry.
* 3. Cluster-wide metrics registry for environments running in a cluster.
*
* Depending on the environment and the node type (primary or worker), it responds to metric
* requests by merging and presenting metrics from appropriate registries.
*/
class MetricsFacade extends events_1.default {
/**
* Create an instance of metrics manager
* @param options - Configuration options for the metrics manager
*/
constructor(options) {
super();
this.options = options;
this.logger = (0, logger_1.SetContext)(
// Stryker disable next-line all
options.logger || new logger_1.DebugLogger(`mdf:registry:metrics:${this.name}`), this.name, this.componentId);
this.port = this.getPort(options.isCluster);
this.aggregator = new Aggregator_1.Aggregator(this.logger, this.port);
this._router = new Router_1.Router(this.aggregator);
// Stryker disable next-line all
this.logger.debug(`Metrics manager created for ${this.name} application`);
}
/**
* Conditionally creates an AggregatorRegistry if the service is running in a cluster.
* @param isCluster - Boolean indicating if the service is running in cluster mode.
* @returns An AggregatorRegistry instance or undefined if not in cluster mode.
*/
getPort(isCluster) {
if (typeof isCluster === 'boolean' && isCluster) {
return new prom_client_1.AggregatorRegistry();
}
else {
return undefined;
}
}
/** @returns The application name */
get name() {
return this.options.name;
}
/** @returns The application identifier */
get componentId() {
return this.options.instanceId;
}
/** @returns An Express router with access to metrics information */
get router() {
return this._router.router;
}
/** @returns Links offered by this service */
get links() {
return { [`${types_1.METRICS_SERVICE_NAME}`]: `/${types_1.METRICS_SERVICE_NAME}` };
}
/** @returns The health status of the component */
get status() {
return core_1.Health.STATUS.PASS;
}
/** @returns Health checks for this service */
get checks() {
return {
[`${this.name}:metrics`]: [
{
status: this.status,
observedUnit: 'metrics',
componentId: this.componentId,
time: new Date().toISOString(),
},
],
};
}
/**
* Registers one or multiple services to be monitored.
* @param services - A single service or an array of services to be registered.
*/
register(services) {
this.aggregator.register(services);
// Stryker disable next-line all
this.logger.debug(`Service(s) registered in metrics aggregator`);
}
/** @returns The registry used by the aggregator */
get registry() {
return this.aggregator.registry;
}
/** @returns Metrics in text/plain format */
async metricsText() {
return this.aggregator.metricsText();
}
/** @returns Metrics in JSON format */
async metricsJSON() {
return this.aggregator.metricsJSON();
}
/**
* Retrieves a single metric by name.
* @param name - The name of the metric.
* @returns The metric or undefined if not found.
*/
getMetric(name) {
return this.aggregator.getMetric(name);
}
/**
* Retrieves a single metric value in Prometheus format.
* @param name - The name of the metric.
* @returns A promise resolved with the metric value as a string.
*/
getMetricAsString(name) {
return this.aggregator.getMetricAsString(name);
}
/**
* Retrieves a single metric value in JSON format.
* @param name - The name of the metric.
* @returns A promise resolved with the metric object or undefined if not found.
*/
async getMetricAsJSON(name) {
return this.aggregator.getMetricAsJSON(name);
}
/** Placeholder for starting the metrics service. */
async start() {
// Implementation might be added in future
this.logger.debug('MetricsFacade start method called.');
}
/** Placeholder for stopping the metrics service. */
async stop() {
// Implementation might be added in future
this.logger.debug('MetricsFacade stop method called.');
}
/** Clears all metrics from the registry. */
async close() {
this.aggregator.clear();
// Stryker disable next-line all
this.logger.debug('Metrics cleared from the registry');
}
}
exports.MetricsFacade = MetricsFacade;
//# sourceMappingURL=MetricsFacade.js.map