@mdf.js/service-registry
Version:
MMS - API - Service Registry
171 lines • 7.37 kB
JavaScript
"use strict";
/**
* 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Observability = void 0;
const tslib_1 = require("tslib");
const cluster_1 = tslib_1.__importDefault(require("cluster"));
const ObservabilityAppManager_1 = require("./ObservabilityAppManager");
const registries_1 = require("./registries");
/**
* Represents a comprehensive observability service that aggregates various registries
* including health checks, metrics, and error logging. This class is responsible for
* managing and initializing these registries, attaching services to them, and integrating
* them into a unified observability application.
*
* The service leverages an `ObservabilityAppManager` to orchestrate the express application
* that serves observability endpoints. It allows for dynamic registration of services
* to enable monitoring, health checks, and error tracking.
*/
class Observability {
/**
* Initializes the observability service with specified options, setting up
* health, metrics, and error registries based on those options.
* @param options - Configuration options for observability, including settings
* for health checks, metrics collection, and error logging.
*/
constructor(options) {
var _a, _b, _c, _d, _e, _f, _g;
this.options = options;
this._healthRegistry = new registries_1.HealthRegistry({
applicationMetadata: this.options.metadata,
isCluster: (_a = this.options.service) === null || _a === void 0 ? void 0 : _a.isCluster,
clusterUpdateInterval: (_b = this.options.service) === null || _b === void 0 ? void 0 : _b.clusterUpdateInterval,
logger: this.options.logger,
});
this._errorsRegistry = new registries_1.ErrorRegistry({
name: this.options.metadata.name,
instanceId: this.options.metadata.instanceId,
maxSize: (_c = this.options.service) === null || _c === void 0 ? void 0 : _c.maxSize,
includeStack: (_d = this.options.service) === null || _d === void 0 ? void 0 : _d.includeStack,
isCluster: (_e = this.options.service) === null || _e === void 0 ? void 0 : _e.isCluster,
clusterUpdateInterval: (_f = this.options.service) === null || _f === void 0 ? void 0 : _f.clusterUpdateInterval,
logger: options.logger,
});
this._metricsRegistry = new registries_1.MetricsRegistry({
name: this.options.metadata.name,
instanceId: this.options.metadata.instanceId,
isCluster: (_g = this.options.service) === null || _g === void 0 ? void 0 : _g.isCluster,
logger: this.options.logger,
});
this._registers = [this._healthRegistry, this._metricsRegistry, this._errorsRegistry];
this._app = new ObservabilityAppManager_1.ObservabilityAppManager(this.options, this._metricsRegistry.registry);
}
/**
* Attaches a new service to be monitored under the observability framework.
* Services are components of your application that you wish to monitor for
* health, track errors for, and collect metrics on.
* @param observable - The service to attach to observability.
*/
attach(observable) {
// Add the service that can emit errors to the errors registry
this._errorsRegistry.register(observable);
// Add the service that can collect metrics to the metrics registry
this._metricsRegistry.register(observable);
// Add the service with health information to the health registry
this._healthRegistry.register(observable);
// Add the service with REST API interface in the observability app
this._app.register(observable);
}
/** Start the observability service */
async start() {
if (this._app.isBuild) {
return;
}
// If the service is running in a cluster or standalone, register the errors summary
if (cluster_1.default.isPrimary) {
this._healthRegistry.register(this._errorsRegistry);
}
// Register all the services in the observability app
this._app.register(this._registers);
// Start all the registers
for (const register of this._registers) {
await register.start();
}
this._app.build();
await this._app.start();
}
/** Stop the observability service */
async stop() {
if (!this._app.isBuild) {
return;
}
await this._app.stop();
this._app.unbuilt();
for (const register of this._registers) {
await register.stop();
}
}
/** Close the observability service */
async close() {
if (!this._app.isBuild) {
return;
}
await this.stop();
for (const register of this._registers) {
if (typeof register.close === 'function') {
await register.close();
}
}
}
/**
* Adds an error to the registry, converting it to a structured format.
* @param error - The error to register.
*/
push(error) {
this._errorsRegistry.push(error);
}
/**
* Adds a timestamped note to the health status.
* @param note - Note to be added.
*/
addNote(note) {
this._healthRegistry.addNote(note);
}
/**
* Update or add a check measure.
* This should be used to inform about the state of resources behind the Component/Microservice,
* for example states of connections with field devices.
*
* The new check will be taking into account in the overall health status.
* The new check will be included in the `checks` object with the key "component:measure".
* If this key already exists, the `componentId` of the `check` parameter will be checked, if
* there is a check with the same `componentId` in the array, the check will be updated, in other
* case the new check will be added to the existing array.
*
* The maximum number external checks is 100
* @param component - component identification
* @param measure - measure identification
* @param check - check to be updated or included
* @returns true, if the check has been updated
*/
addCheck(component, measure, check) {
return this._healthRegistry.addCheck(component, measure, check);
}
/** @returns The health of the monitored application */
get health() {
return this._healthRegistry.health;
}
/** @returns The status of the monitored application */
get status() {
return this._healthRegistry.status;
}
/** @returns The metrics of the monitored application */
get metrics() {
return this._metricsRegistry.metricsJSON();
}
/** @returns The errors of the monitored application */
get errors() {
return this._errorsRegistry.errors;
}
/** @returns The observability rest api access end points */
get links() {
return this._app.links;
}
}
exports.Observability = Observability;
//# sourceMappingURL=Observability.js.map