brainy/src/utils/performanceMonitor.ts
David Snelling 9c87982a7d 🧠 Brainy 2.0.0 - Zero-Configuration AI Database with Triple Intelligence™
MAJOR RELEASE: Complete evolution of Brainy with groundbreaking features and performance.

🎯 KEY FEATURES:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Triple Intelligence™ Engine
  - Unified Vector + Metadata + Graph search
  - O(log n) performance on all operations
  - 3ms average search latency at any scale

 API Consolidation
  - 15+ search methods → 2 clean APIs
  - search() for vector similarity
  - find() for natural language queries

 Natural Language Processing
  - 220+ pre-computed NLP patterns
  - Instant context understanding
  - "Show me recent React components with tests"

 Zero Configuration
  - Works instantly, no setup required
  - Built-in embedding models (no API keys)
  - Smart defaults for everything
  - Automatic optimization

 Enterprise Features (Free for Everyone)
  - Scales to 10M+ items
  - Write-Ahead Logging (WAL) for durability
  - Distributed architecture with sharding
  - Read/write separation
  - Connection pooling & request deduplication
  - Built-in monitoring & health checks

 Universal Compatibility
  - Node.js, Browser, Edge Workers
  - 4 Storage Adapters (Memory, FileSystem, OPFS, S3)
  - TypeScript with full type safety
  - Worker-based embeddings

📦 WHAT'S INCLUDED:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Core AI Database with HNSW indexing
• 19 Production-ready augmentations
• Universal Memory Manager
• Complete CLI with all commands
• Brain Cloud integration (soulcraft.com)
• Comprehensive documentation
• 52 test files with 400+ tests
• Migration guide from 1.x

📊 PERFORMANCE:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Initialize: 450ms (24MB memory)
• Search: 3ms average (up to 10M items)
• Metadata Filter: 0.8ms (O(log n))
• Bulk Import: 2.3s per 1000 items
• Production Scale: 5.8ms at 10M items

🔧 TECHNICAL IMPROVEMENTS:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• TypeScript compilation: 153 errors → 0
• Memory usage: 200MB → 24MB baseline
• Circular dependencies resolved
• Worker thread communication fixed
• Storage adapter consistency
• Request coalescing for 3x performance

🛠️ CLI FEATURES:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• brainy add - Smart data ingestion
• brainy find - Natural language search
• brainy search - Vector similarity
• brainy chat - AI conversation mode
• brainy cloud - Brain Cloud integration
• brainy augment - Manage extensions
• 100% API compatibility

📚 DOCUMENTATION:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Professional README with examples
• Quick Start guide (5 minutes)
• Enterprise Features guide
• Migration guide from 1.x
• API reference
• Architecture documentation

🌟 USE CASES:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• AI memory layer for chatbots
• Semantic document search
• Code intelligence platforms
• Knowledge management systems
• Real-time recommendation engines
• Customer support automation

MIT License - Enterprise features included free for everyone.
No premium tiers, no paywalls, no limits.

Built with ❤️ by the Brainy community.
Visit https://soulcraft.com for Brain Cloud integration.
2025-08-26 12:32:21 -07:00

496 lines
No EOL
14 KiB
TypeScript

/**
* Performance Monitor
* Automatically tracks and optimizes system performance
* Provides real-time insights and auto-tuning recommendations
*/
import { createModuleLogger } from './logger.js'
import { getGlobalSocketManager } from './adaptiveSocketManager.js'
import { getGlobalBackpressure } from './adaptiveBackpressure.js'
interface PerformanceMetrics {
// Operation metrics
totalOperations: number
successfulOperations: number
failedOperations: number
averageLatency: number
p95Latency: number
p99Latency: number
// Throughput metrics
operationsPerSecond: number
bytesPerSecond: number
// Resource metrics
memoryUsage: number
cpuUsage: number
socketUtilization: number
queueDepth: number
// Health indicators
errorRate: number
healthScore: number // 0-100
}
interface PerformanceTrend {
metric: string
direction: 'improving' | 'degrading' | 'stable'
changeRate: number
prediction: number
}
/**
* Comprehensive performance monitoring and optimization
*/
export class PerformanceMonitor {
private logger = createModuleLogger('PerformanceMonitor')
// Current metrics
private metrics: PerformanceMetrics = {
totalOperations: 0,
successfulOperations: 0,
failedOperations: 0,
averageLatency: 0,
p95Latency: 0,
p99Latency: 0,
operationsPerSecond: 0,
bytesPerSecond: 0,
memoryUsage: 0,
cpuUsage: 0,
socketUtilization: 0,
queueDepth: 0,
errorRate: 0,
healthScore: 100
}
// Historical data for trend analysis
private history: PerformanceMetrics[] = []
private maxHistorySize = 1000
// Operation tracking
private operationLatencies: number[] = []
private operationSizes: number[] = []
private lastReset = Date.now()
private resetInterval = 60000 // Reset counters every minute
// CPU tracking
private lastCpuUsage = process.cpuUsage ? process.cpuUsage() : null
private lastCpuCheck = Date.now()
// Alert thresholds
private thresholds = {
errorRate: 0.05, // 5% error rate
latencyP95: 5000, // 5 second P95
memoryUsage: 0.8, // 80% memory
cpuUsage: 0.9, // 90% CPU
healthScore: 70 // Health score below 70
}
// Optimization recommendations
private recommendations: string[] = []
// Auto-optimization state
private autoOptimizeEnabled = true
private lastOptimization = Date.now()
private optimizationInterval = 30000 // Optimize every 30 seconds
/**
* Track an operation completion
*/
public trackOperation(
success: boolean,
latency: number,
bytes: number = 0
): void {
// Update counters
this.metrics.totalOperations++
if (success) {
this.metrics.successfulOperations++
} else {
this.metrics.failedOperations++
}
// Track latency
this.operationLatencies.push(latency)
if (this.operationLatencies.length > 10000) {
this.operationLatencies = this.operationLatencies.slice(-5000)
}
// Track size
if (bytes > 0) {
this.operationSizes.push(bytes)
if (this.operationSizes.length > 10000) {
this.operationSizes = this.operationSizes.slice(-5000)
}
}
// Update metrics periodically
this.updateMetrics()
}
/**
* Update all metrics
*/
private updateMetrics(): void {
const now = Date.now()
const timeSinceReset = (now - this.lastReset) / 1000
// Calculate latency percentiles
if (this.operationLatencies.length > 0) {
const sorted = [...this.operationLatencies].sort((a, b) => a - b)
const p95Index = Math.floor(sorted.length * 0.95)
const p99Index = Math.floor(sorted.length * 0.99)
this.metrics.averageLatency = sorted.reduce((a, b) => a + b, 0) / sorted.length
this.metrics.p95Latency = sorted[p95Index] || 0
this.metrics.p99Latency = sorted[p99Index] || 0
}
// Calculate throughput
if (timeSinceReset > 0) {
this.metrics.operationsPerSecond = this.metrics.totalOperations / timeSinceReset
const totalBytes = this.operationSizes.reduce((a, b) => a + b, 0)
this.metrics.bytesPerSecond = totalBytes / timeSinceReset
}
// Calculate error rate
this.metrics.errorRate = this.metrics.totalOperations > 0
? this.metrics.failedOperations / this.metrics.totalOperations
: 0
// Update resource metrics
this.updateResourceMetrics()
// Calculate health score
this.calculateHealthScore()
// Store in history
this.history.push({ ...this.metrics })
if (this.history.length > this.maxHistorySize) {
this.history.shift()
}
// Check for alerts
this.checkAlerts()
// Auto-optimize if enabled
if (this.autoOptimizeEnabled && now - this.lastOptimization > this.optimizationInterval) {
this.autoOptimize()
this.lastOptimization = now
}
// Reset counters periodically
if (now - this.lastReset > this.resetInterval) {
this.resetCounters()
}
}
/**
* Update resource metrics
*/
private updateResourceMetrics(): void {
// Memory usage
if (typeof process !== 'undefined' && process.memoryUsage) {
const memUsage = process.memoryUsage()
this.metrics.memoryUsage = memUsage.heapUsed / memUsage.heapTotal
}
// CPU usage (Node.js only)
if (this.lastCpuUsage && process.cpuUsage) {
const currentCpuUsage = process.cpuUsage()
const now = Date.now()
const timeDiff = now - this.lastCpuCheck
if (timeDiff > 1000) { // Update CPU every second
const userDiff = currentCpuUsage.user - this.lastCpuUsage.user
const systemDiff = currentCpuUsage.system - this.lastCpuUsage.system
const totalDiff = userDiff + systemDiff
// CPU percentage (approximate)
this.metrics.cpuUsage = totalDiff / (timeDiff * 1000)
this.lastCpuUsage = currentCpuUsage
this.lastCpuCheck = now
}
}
// Get metrics from socket manager
const socketMetrics = getGlobalSocketManager().getMetrics()
this.metrics.socketUtilization = socketMetrics.socketUtilization
// Get metrics from backpressure system
const backpressureStatus = getGlobalBackpressure().getStatus()
this.metrics.queueDepth = backpressureStatus.queueLength
}
/**
* Calculate overall health score
*/
private calculateHealthScore(): void {
let score = 100
// Deduct points for high error rate
if (this.metrics.errorRate > 0.01) {
score -= Math.min(30, this.metrics.errorRate * 300)
}
// Deduct points for high latency
if (this.metrics.p95Latency > 3000) {
score -= Math.min(20, (this.metrics.p95Latency - 3000) / 100)
}
// Deduct points for high memory usage
if (this.metrics.memoryUsage > 0.7) {
score -= Math.min(20, (this.metrics.memoryUsage - 0.7) * 66)
}
// Deduct points for high CPU usage
if (this.metrics.cpuUsage > 0.8) {
score -= Math.min(15, (this.metrics.cpuUsage - 0.8) * 75)
}
// Deduct points for low throughput
if (this.metrics.operationsPerSecond < 1 && this.metrics.totalOperations > 10) {
score -= 10
}
// Deduct points for queue depth
if (this.metrics.queueDepth > 100) {
score -= Math.min(15, this.metrics.queueDepth / 20)
}
this.metrics.healthScore = Math.max(0, Math.min(100, score))
}
/**
* Check for alert conditions
*/
private checkAlerts(): void {
const alerts: string[] = []
if (this.metrics.errorRate > this.thresholds.errorRate) {
alerts.push(`High error rate: ${(this.metrics.errorRate * 100).toFixed(1)}%`)
}
if (this.metrics.p95Latency > this.thresholds.latencyP95) {
alerts.push(`High P95 latency: ${this.metrics.p95Latency}ms`)
}
if (this.metrics.memoryUsage > this.thresholds.memoryUsage) {
alerts.push(`High memory usage: ${(this.metrics.memoryUsage * 100).toFixed(1)}%`)
}
if (this.metrics.cpuUsage > this.thresholds.cpuUsage) {
alerts.push(`High CPU usage: ${(this.metrics.cpuUsage * 100).toFixed(1)}%`)
}
if (this.metrics.healthScore < this.thresholds.healthScore) {
alerts.push(`Low health score: ${this.metrics.healthScore.toFixed(0)}`)
}
if (alerts.length > 0) {
this.logger.warn('Performance alerts', { alerts, metrics: this.metrics })
}
}
/**
* Auto-optimize system based on metrics
*/
private autoOptimize(): void {
this.recommendations = []
// Analyze trends
const trends = this.analyzeTrends()
// Generate recommendations based on metrics and trends
if (this.metrics.errorRate > 0.02) {
this.recommendations.push('Reduce load or increase timeouts due to high error rate')
}
if (this.metrics.p95Latency > 3000) {
this.recommendations.push('Increase batch size or socket limits to improve latency')
}
if (this.metrics.memoryUsage > 0.7) {
this.recommendations.push('Reduce cache sizes or batch sizes to free memory')
}
if (this.metrics.queueDepth > 50) {
this.recommendations.push('Increase concurrency limits to reduce queue depth')
}
// Check for degrading trends
trends.forEach(trend => {
if (trend.direction === 'degrading' && Math.abs(trend.changeRate) > 0.1) {
this.recommendations.push(`${trend.metric} is degrading at ${(trend.changeRate * 100).toFixed(1)}% per minute`)
}
})
// Log recommendations if any
if (this.recommendations.length > 0) {
this.logger.info('Performance optimization recommendations', {
recommendations: this.recommendations,
metrics: this.metrics
})
}
}
/**
* Analyze performance trends
*/
private analyzeTrends(): PerformanceTrend[] {
const trends: PerformanceTrend[] = []
if (this.history.length < 10) {
return trends // Not enough data
}
// Get recent history
const recent = this.history.slice(-20)
const older = this.history.slice(-40, -20)
// Compare key metrics
const metricsToAnalyze = [
'errorRate',
'averageLatency',
'operationsPerSecond',
'memoryUsage',
'healthScore'
] as const
metricsToAnalyze.forEach(metric => {
const recentAvg = recent.reduce((sum, m) => sum + m[metric], 0) / recent.length
const olderAvg = older.length > 0
? older.reduce((sum, m) => sum + m[metric], 0) / older.length
: recentAvg
const changeRate = olderAvg !== 0 ? (recentAvg - olderAvg) / olderAvg : 0
let direction: 'improving' | 'degrading' | 'stable' = 'stable'
if (Math.abs(changeRate) > 0.05) { // 5% threshold
// For error rate and latency, increase is bad
if (metric === 'errorRate' || metric === 'averageLatency' || metric === 'memoryUsage') {
direction = changeRate > 0 ? 'degrading' : 'improving'
} else {
// For throughput and health score, increase is good
direction = changeRate > 0 ? 'improving' : 'degrading'
}
}
// Simple linear prediction
const prediction = recentAvg + (recentAvg * changeRate)
trends.push({
metric,
direction,
changeRate,
prediction
})
})
return trends
}
/**
* Reset counters
*/
private resetCounters(): void {
this.metrics.totalOperations = 0
this.metrics.successfulOperations = 0
this.metrics.failedOperations = 0
this.operationSizes = []
this.lastReset = Date.now()
}
/**
* Get current metrics
*/
public getMetrics(): Readonly<PerformanceMetrics> {
return { ...this.metrics }
}
/**
* Get performance trends
*/
public getTrends(): PerformanceTrend[] {
return this.analyzeTrends()
}
/**
* Get recommendations
*/
public getRecommendations(): string[] {
return [...this.recommendations]
}
/**
* Get performance report
*/
public getReport(): {
metrics: PerformanceMetrics
trends: PerformanceTrend[]
recommendations: string[]
socketConfig: any
backpressureStatus: any
} {
return {
metrics: this.getMetrics(),
trends: this.getTrends(),
recommendations: this.getRecommendations(),
socketConfig: getGlobalSocketManager().getConfig(),
backpressureStatus: getGlobalBackpressure().getStatus()
}
}
/**
* Enable/disable auto-optimization
*/
public setAutoOptimize(enabled: boolean): void {
this.autoOptimizeEnabled = enabled
this.logger.info(`Auto-optimization ${enabled ? 'enabled' : 'disabled'}`)
}
/**
* Reset all metrics and history
*/
public reset(): void {
this.metrics = {
totalOperations: 0,
successfulOperations: 0,
failedOperations: 0,
averageLatency: 0,
p95Latency: 0,
p99Latency: 0,
operationsPerSecond: 0,
bytesPerSecond: 0,
memoryUsage: 0,
cpuUsage: 0,
socketUtilization: 0,
queueDepth: 0,
errorRate: 0,
healthScore: 100
}
this.history = []
this.operationLatencies = []
this.operationSizes = []
this.recommendations = []
this.lastReset = Date.now()
this.logger.info('Performance monitor reset')
}
}
// Global singleton instance
let globalMonitor: PerformanceMonitor | null = null
/**
* Get the global performance monitor instance
*/
export function getGlobalPerformanceMonitor(): PerformanceMonitor {
if (!globalMonitor) {
globalMonitor = new PerformanceMonitor()
}
return globalMonitor
}