@ahmedhegazee/nestjs-telescope
Version:
Advanced observability and monitoring solution for NestJS applications with ML-powered analytics, enterprise features, and production-ready scaling
318 lines • 12.1 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var WatcherRegistryService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatcherRegistryService = void 0;
const common_1 = require("@nestjs/common");
const core_1 = require("@nestjs/core");
const enhanced_entry_manager_service_1 = require("../core/services/enhanced-entry-manager.service");
const common_2 = require("@nestjs/common");
let WatcherRegistryService = WatcherRegistryService_1 = class WatcherRegistryService {
constructor(moduleRef, entryManager, config) {
this.moduleRef = moduleRef;
this.entryManager = entryManager;
this.config = config;
this.logger = new common_1.Logger(WatcherRegistryService_1.name);
this.watchers = new Map();
this.watcherMetadata = new Map();
this.dependencyGraph = new Map();
this.initialized = false;
}
async onModuleInit() {
await this.discoverWatchers();
this.buildDependencyGraph();
await this.initializeWatchers();
this.initialized = true;
this.logger.log('Watcher registry initialized');
}
register(watcher, metadata = {}) {
if (this.watchers.has(watcher.name)) {
throw new Error(`Watcher '${watcher.name}' is already registered`);
}
this.watchers.set(watcher.name, watcher);
this.watcherMetadata.set(watcher.name, {
name: watcher.name,
enabled: watcher.isEnabled,
priority: metadata.priority || 100,
tags: metadata.tags || [],
dependencies: metadata.dependencies || [],
entriesProcessed: 0
});
this.logger.debug(`Registered watcher: ${watcher.name}`);
}
unregister(name) {
const watcher = this.watchers.get(name);
if (!watcher)
return false;
const dependents = this.getDependents(name);
if (dependents.length > 0) {
throw new Error(`Cannot unregister watcher '${name}' - it has dependents: ${dependents.join(', ')}`);
}
this.watchers.delete(name);
this.watcherMetadata.delete(name);
this.dependencyGraph.delete(name);
this.logger.debug(`Unregistered watcher: ${name}`);
return true;
}
async enable(name) {
const watcher = this.watchers.get(name);
if (!watcher) {
throw new Error(`Watcher '${name}' not found`);
}
const metadata = this.watcherMetadata.get(name);
for (const dependency of metadata.dependencies) {
const depWatcher = this.watchers.get(dependency);
if (!depWatcher || !depWatcher.isEnabled) {
throw new Error(`Dependency '${dependency}' is not enabled for watcher '${name}'`);
}
}
watcher.enable();
metadata.enabled = true;
this.logger.log(`Enabled watcher: ${name}`);
}
async disable(name) {
const watcher = this.watchers.get(name);
if (!watcher) {
throw new Error(`Watcher '${name}' not found`);
}
const dependents = this.getDependents(name);
if (dependents.length > 0) {
throw new Error(`Cannot disable watcher '${name}' - it has dependents: ${dependents.join(', ')}`);
}
watcher.disable();
const metadata = this.watcherMetadata.get(name);
metadata.enabled = false;
this.logger.log(`Disabled watcher: ${name}`);
}
async enableAll() {
const sortedWatchers = this.getSortedWatchers();
for (const watcher of sortedWatchers) {
try {
if (!watcher.isEnabled) {
await this.enable(watcher.name);
}
}
catch (error) {
this.logger.error(`Failed to enable watcher '${watcher.name}':`, error);
}
}
}
async disableAll() {
const sortedWatchers = this.getSortedWatchers().reverse();
for (const watcher of sortedWatchers) {
try {
if (watcher.isEnabled) {
await this.disable(watcher.name);
}
}
catch (error) {
this.logger.error(`Failed to disable watcher '${watcher.name}':`, error);
}
}
}
async restart(name) {
await this.disable(name);
await this.enable(name);
}
getWatcher(name) {
return this.watchers.get(name);
}
getWatcherMetadata(name) {
return this.watcherMetadata.get(name);
}
getAllWatchers() {
return Array.from(this.watchers.values());
}
getEnabledWatchers() {
return Array.from(this.watchers.values()).filter(watcher => watcher.isEnabled);
}
getDisabledWatchers() {
return Array.from(this.watchers.values()).filter(watcher => !watcher.isEnabled);
}
getWatchersByTag(tag) {
const watchers = [];
for (const [name, metadata] of this.watcherMetadata) {
if (metadata.tags.includes(tag)) {
const watcher = this.watchers.get(name);
if (watcher) {
watchers.push(watcher);
}
}
}
return watchers;
}
getStatistics() {
const allWatchers = Array.from(this.watcherMetadata.values());
const enabledWatchers = allWatchers.filter(w => w.enabled);
const disabledWatchers = allWatchers.filter(w => !w.enabled);
return {
total: allWatchers.length,
enabled: enabledWatchers.length,
disabled: disabledWatchers.length,
totalEntriesProcessed: allWatchers.reduce((sum, w) => sum + w.entriesProcessed, 0),
watchers: allWatchers.map(w => ({
name: w.name,
enabled: w.enabled,
priority: w.priority,
tags: w.tags,
dependencies: w.dependencies,
lastActivity: w.lastActivity,
entriesProcessed: w.entriesProcessed
}))
};
}
async processEntry(entry, watcherName) {
try {
if (watcherName) {
const metadata = this.watcherMetadata.get(watcherName);
if (metadata) {
metadata.lastActivity = new Date();
metadata.entriesProcessed++;
}
}
await this.entryManager.process(entry);
}
catch (error) {
this.logger.error(`Failed to process entry from watcher '${watcherName}':`, error);
throw error;
}
}
async processBatch(entries, watcherName) {
try {
if (watcherName) {
const metadata = this.watcherMetadata.get(watcherName);
if (metadata) {
metadata.lastActivity = new Date();
metadata.entriesProcessed += entries.length;
}
}
await this.entryManager.processBatch(entries);
}
catch (error) {
this.logger.error(`Failed to process batch from watcher '${watcherName}':`, error);
throw error;
}
}
async healthCheck() {
const results = {};
let overallHealth = true;
for (const [name, watcher] of this.watchers) {
try {
if ('healthCheck' in watcher && typeof watcher.healthCheck === 'function') {
const isHealthy = await watcher.healthCheck();
results[name] = isHealthy;
if (!isHealthy)
overallHealth = false;
}
else {
results[name] = watcher.isEnabled;
}
}
catch (error) {
this.logger.error(`Health check failed for watcher '${name}':`, error);
results[name] = false;
overallHealth = false;
}
}
return {
healthy: overallHealth,
watchers: results,
timestamp: new Date()
};
}
async discoverWatchers() {
this.logger.debug('Watcher discovery completed');
}
buildDependencyGraph() {
for (const [name, metadata] of this.watcherMetadata) {
this.dependencyGraph.set(name, metadata.dependencies);
}
}
async initializeWatchers() {
const sortedWatchers = this.getSortedWatchers();
for (const watcher of sortedWatchers) {
try {
const watcherConfig = this.config.watchers?.[watcher.name];
if (watcherConfig?.enabled !== false) {
await this.enable(watcher.name);
}
}
catch (error) {
this.logger.error(`Failed to initialize watcher '${watcher.name}':`, error);
}
}
}
getSortedWatchers() {
const watchers = Array.from(this.watchers.values());
return watchers.sort((a, b) => {
const metaA = this.watcherMetadata.get(a.name);
const metaB = this.watcherMetadata.get(b.name);
return metaA.priority - metaB.priority;
});
}
getDependents(name) {
const dependents = [];
for (const [watcherName, metadata] of this.watcherMetadata) {
if (metadata.dependencies.includes(name)) {
dependents.push(watcherName);
}
}
return dependents;
}
async cleanup() {
await this.disableAll();
for (const [name, watcher] of this.watchers) {
try {
await watcher.cleanup();
this.logger.debug(`Cleaned up watcher: ${name}`);
}
catch (error) {
this.logger.error(`Failed to cleanup watcher '${name}':`, error);
}
}
this.watchers.clear();
this.watcherMetadata.clear();
this.dependencyGraph.clear();
this.initialized = false;
this.logger.log('Watcher registry cleaned up');
}
async updateWatcherConfig(name, config) {
const metadata = this.watcherMetadata.get(name);
if (!metadata) {
throw new Error(`Watcher '${name}' not found`);
}
Object.assign(metadata, config);
this.logger.debug(`Updated config for watcher: ${name}`);
}
isInitialized() {
return this.initialized;
}
hasWatcher(name) {
return this.watchers.has(name);
}
getWatcherCount() {
return this.watchers.size;
}
getEnabledWatcherCount() {
return this.getEnabledWatchers().length;
}
};
exports.WatcherRegistryService = WatcherRegistryService;
exports.WatcherRegistryService = WatcherRegistryService = WatcherRegistryService_1 = __decorate([
(0, common_1.Injectable)(),
__param(2, (0, common_2.Inject)('TELESCOPE_CONFIG')),
__metadata("design:paramtypes", [core_1.ModuleRef,
enhanced_entry_manager_service_1.EnhancedEntryManagerService, Object])
], WatcherRegistryService);
//# sourceMappingURL=watcher-registry.service.js.map