CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB Recovery Status: - Successfully recovered brainy.ts from compiled JavaScript - All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.) - Neural subsystem intact (562KB embedded patterns, NLP working) - Augmentation pipeline operational (20+ augmentations) - HNSW clustering system complete - Triple Intelligence compiled (needs constructor fix) - Test suite validates functionality Changes preserved: - 898 files with changes from last 3 days - 144,475 insertions - All augmentation improvements - All test coverage enhancements - Complete v3.0 feature set This is a LOCAL checkpoint only - contains recovered work after corruption incident. Created backup in .backups/brainy-full-20250910-151314.tar.gz Branch: recovery-checkpoint-20250910-151433 Date: Wed Sep 10 03:18:04 PM PDT 2025
228 lines
No EOL
7.6 KiB
JavaScript
228 lines
No EOL
7.6 KiB
JavaScript
/**
|
|
* Monitoring Augmentation - Optional Health & Performance Monitoring
|
|
*
|
|
* Replaces the hardcoded HealthMonitor in Brainy with an optional augmentation.
|
|
* Provides health checks, performance monitoring, and distributed system tracking.
|
|
*
|
|
* Zero-config: Automatically enabled for distributed deployments
|
|
* Can be disabled or customized via augmentation registry
|
|
*/
|
|
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
import { HealthMonitor } from '../distributed/healthMonitor.js';
|
|
import { DistributedConfigManager as ConfigManager } from '../distributed/configManager.js';
|
|
/**
|
|
* MonitoringAugmentation - Makes health monitoring optional and pluggable
|
|
*
|
|
* Features:
|
|
* - Health status tracking
|
|
* - Performance monitoring
|
|
* - Error rate tracking
|
|
* - Distributed system health
|
|
* - Zero-config with smart defaults
|
|
*/
|
|
export class MonitoringAugmentation extends BaseAugmentation {
|
|
constructor(config = {}) {
|
|
super();
|
|
this.metadata = 'readonly'; // Reads metadata for monitoring
|
|
this.name = 'monitoring';
|
|
this.timing = 'after';
|
|
this.operations = ['search', 'find', 'similar', 'add', 'update', 'delete', 'relate', 'unrelate', 'all'];
|
|
this.priority = 30; // Low priority, observability layer
|
|
this.healthMonitor = null;
|
|
this.configManager = null;
|
|
this.requestStartTimes = new Map();
|
|
this.config = {
|
|
enabled: true,
|
|
healthCheckInterval: 30000, // 30 seconds
|
|
metricsInterval: 60000, // 1 minute
|
|
trackLatency: true,
|
|
trackErrors: true,
|
|
trackCacheMetrics: true,
|
|
exposeHealthEndpoint: true,
|
|
...config
|
|
};
|
|
}
|
|
async onInitialize() {
|
|
if (!this.config.enabled) {
|
|
this.log('Monitoring augmentation disabled by configuration');
|
|
return;
|
|
}
|
|
// Initialize config manager and health monitor (requires storage)
|
|
if (this.context?.storage) {
|
|
this.configManager = new ConfigManager(this.context.storage);
|
|
this.healthMonitor = new HealthMonitor(this.configManager);
|
|
this.healthMonitor.start();
|
|
}
|
|
else {
|
|
this.log('Storage not available - health monitoring disabled', 'warn');
|
|
}
|
|
this.log('Monitoring augmentation initialized');
|
|
}
|
|
async onShutdown() {
|
|
if (this.healthMonitor) {
|
|
this.healthMonitor.stop();
|
|
this.healthMonitor = null;
|
|
}
|
|
this.configManager = null;
|
|
this.requestStartTimes.clear();
|
|
this.log('Monitoring augmentation shut down');
|
|
}
|
|
/**
|
|
* Execute augmentation - track health metrics
|
|
*/
|
|
async execute(operation, params, next) {
|
|
// If monitoring disabled, just pass through
|
|
if (!this.healthMonitor || !this.config.enabled) {
|
|
return next();
|
|
}
|
|
// Generate request ID for tracking
|
|
const requestId = `${operation}-${Date.now()}-${Math.random()}`;
|
|
// Track request start time
|
|
if (this.config.trackLatency) {
|
|
this.requestStartTimes.set(requestId, Date.now());
|
|
}
|
|
try {
|
|
// Execute operation
|
|
const result = await next();
|
|
// Track successful operation
|
|
if (this.config.trackLatency) {
|
|
const startTime = this.requestStartTimes.get(requestId);
|
|
if (startTime) {
|
|
const latency = Date.now() - startTime;
|
|
this.healthMonitor.recordRequest(latency, false);
|
|
this.requestStartTimes.delete(requestId);
|
|
}
|
|
}
|
|
// Update vector count for 'add' operations
|
|
if (operation === 'add' && this.context?.brain) {
|
|
try {
|
|
const count = await this.context.brain.getNounCount();
|
|
this.healthMonitor.updateVectorCount(count);
|
|
}
|
|
catch (e) {
|
|
// Ignore count update errors
|
|
}
|
|
}
|
|
// Track cache metrics for search operations
|
|
if (operation === 'search' && this.config.trackCacheMetrics) {
|
|
// Check if result came from cache (would be set by cache augmentation)
|
|
const fromCache = params._fromCache || false;
|
|
this.healthMonitor.recordCacheAccess(fromCache);
|
|
}
|
|
return result;
|
|
}
|
|
catch (error) {
|
|
// Track error
|
|
if (this.config.trackErrors) {
|
|
const startTime = this.requestStartTimes.get(requestId);
|
|
if (startTime) {
|
|
const latency = Date.now() - startTime;
|
|
this.healthMonitor.recordRequest(latency, true);
|
|
this.requestStartTimes.delete(requestId);
|
|
}
|
|
else {
|
|
this.healthMonitor.recordRequest(0, true);
|
|
}
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
/**
|
|
* Get health status
|
|
*/
|
|
getHealthStatus() {
|
|
if (!this.healthMonitor) {
|
|
return {
|
|
status: 'disabled',
|
|
enabled: false,
|
|
uptime: 0,
|
|
vectorCount: 0,
|
|
requestRate: 0,
|
|
errorRate: 0,
|
|
cacheHitRate: 0
|
|
};
|
|
}
|
|
return {
|
|
status: 'healthy',
|
|
enabled: true,
|
|
...this.healthMonitor.getHealthEndpointData()
|
|
};
|
|
}
|
|
/**
|
|
* Get health endpoint data (for API exposure)
|
|
*/
|
|
getHealthEndpointData() {
|
|
if (!this.healthMonitor) {
|
|
return {
|
|
status: 'disabled',
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
}
|
|
return this.healthMonitor.getHealthEndpointData();
|
|
}
|
|
/**
|
|
* Update vector count manually
|
|
*/
|
|
updateVectorCount(count) {
|
|
if (this.healthMonitor) {
|
|
this.healthMonitor.updateVectorCount(count);
|
|
}
|
|
}
|
|
/**
|
|
* Record custom health metric
|
|
*/
|
|
recordCustomMetric(name, value) {
|
|
if (this.healthMonitor) {
|
|
// Health monitor could be extended to track custom metrics
|
|
this.log(`Custom metric recorded: ${name}=${value}`, 'info');
|
|
}
|
|
}
|
|
/**
|
|
* Check if system is healthy
|
|
*/
|
|
isHealthy() {
|
|
if (!this.healthMonitor)
|
|
return true; // If disabled, assume healthy
|
|
const data = this.healthMonitor.getHealthEndpointData();
|
|
// Define health criteria
|
|
const errorRateThreshold = 0.05; // 5% error rate
|
|
const minUptime = 60000; // 1 minute
|
|
return (data.errorRate < errorRateThreshold &&
|
|
data.uptime > minUptime);
|
|
}
|
|
/**
|
|
* Get uptime in milliseconds
|
|
*/
|
|
getUptime() {
|
|
if (!this.healthMonitor)
|
|
return 0;
|
|
const data = this.healthMonitor.getHealthEndpointData();
|
|
return data.uptime || 0;
|
|
}
|
|
/**
|
|
* Force health check
|
|
*/
|
|
async checkHealth() {
|
|
if (!this.healthMonitor)
|
|
return true;
|
|
// Perform active health check
|
|
try {
|
|
// Could ping storage, check memory, etc.
|
|
if (this.context?.storage) {
|
|
await this.context.storage.getStatistics?.();
|
|
}
|
|
return true;
|
|
}
|
|
catch (error) {
|
|
this.log('Health check failed', 'warn');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Factory function for zero-config monitoring augmentation
|
|
*/
|
|
export function createMonitoringAugmentation(config) {
|
|
return new MonitoringAugmentation(config);
|
|
}
|
|
//# sourceMappingURL=monitoringAugmentation.js.map
|