snow-flow 1.3.25 → 1.3.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/config.json +33 -9
- package/.claude-flow/queen/queen-memory.db +0 -0
- package/.roo/README.md +56 -0
- package/.roo/workflows/basic-tdd.json +32 -0
- package/.roomodes +122 -0
- package/CLAUDE.md +140 -752
- package/claude-flow +30 -75
- package/dist/cli.js +250 -7
- package/dist/compliance/advanced-compliance-system.js +857 -0
- package/dist/compliance/index.js +8 -0
- package/dist/documentation/index.js +8 -0
- package/dist/documentation/self-documenting-system.js +1006 -0
- package/dist/healing/index.js +8 -0
- package/dist/healing/self-healing-system.js +1041 -0
- package/dist/intelligence/performance-recommendations-engine.js +479 -4
- package/dist/managers/scope-manager.js +5 -2
- package/dist/mcp/servicenow-deployment-mcp.js +113 -15
- package/dist/mcp/servicenow-flow-composer-mcp.js +4 -2
- package/dist/mcp/servicenow-intelligent-mcp.js +351 -0
- package/dist/mcp/servicenow-operations-mcp.js +2 -2
- package/dist/memory/memory-system.js +146 -0
- package/dist/monitoring/enhanced-monitoring-system.js +1085 -0
- package/dist/optimization/cost-optimization-engine.js +771 -0
- package/dist/optimization/flow-performance-optimizer.js +723 -0
- package/dist/optimization/index.js +10 -0
- package/dist/orchestration/flow-update-orchestrator.js +648 -0
- package/dist/rollback/smart-rollback-system.js +462 -0
- package/dist/templates/flow-template-system.js +625 -0
- package/dist/testing/flow-testing-automation.js +641 -0
- package/dist/testing/integration-test-suite.js +890 -0
- package/dist/utils/flow-structure-builder.js +1 -1
- package/dist/utils/servicenow-client.js +50 -2
- package/dist/utils/snow-oauth.js +66 -8
- package/dist/utils/xml-first-flow-generator.js +6 -0
- package/dist/version.js +13 -1
- package/package.json +1 -1
|
@@ -0,0 +1,1041 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 🤖 Self-Healing System for Autonomous Error Recovery
|
|
4
|
+
*
|
|
5
|
+
* Advanced autonomous system that detects, diagnoses, and automatically
|
|
6
|
+
* recovers from errors without manual intervention, ensuring maximum
|
|
7
|
+
* system availability and reliability.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SelfHealingSystem = void 0;
|
|
11
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
12
|
+
class SelfHealingSystem {
|
|
13
|
+
constructor(client, memory) {
|
|
14
|
+
this.healingProfiles = new Map();
|
|
15
|
+
this.activeIncidents = new Map();
|
|
16
|
+
this.errorPatterns = new Map();
|
|
17
|
+
this.recoveryStrategies = new Map();
|
|
18
|
+
this.monitoringActive = true;
|
|
19
|
+
this.logger = new logger_js_1.Logger('SelfHealingSystem');
|
|
20
|
+
this.client = client;
|
|
21
|
+
this.memory = memory;
|
|
22
|
+
this.learningEngine = new LearningEngine(memory);
|
|
23
|
+
this.initializeRecoveryStrategies();
|
|
24
|
+
this.startHealthMonitoring();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Perform system health assessment and healing
|
|
28
|
+
*/
|
|
29
|
+
async performHealthCheck(request = {}) {
|
|
30
|
+
this.logger.info('🏥 Performing system health check', request);
|
|
31
|
+
const profileId = `heal_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
|
32
|
+
const startTime = Date.now();
|
|
33
|
+
try {
|
|
34
|
+
// Detect health incidents
|
|
35
|
+
const incidents = await this.detectHealthIncidents(request);
|
|
36
|
+
// Analyze root causes
|
|
37
|
+
for (const incident of incidents) {
|
|
38
|
+
incident.rootCause = await this.analyzeRootCause(incident);
|
|
39
|
+
}
|
|
40
|
+
// Identify error patterns
|
|
41
|
+
const patterns = await this.identifyErrorPatterns(incidents);
|
|
42
|
+
// Generate predictions if requested
|
|
43
|
+
let predictions = [];
|
|
44
|
+
if (request.predictive) {
|
|
45
|
+
predictions = await this.generateHealthPredictions(incidents, patterns);
|
|
46
|
+
}
|
|
47
|
+
// Create healing actions
|
|
48
|
+
const healingActions = await this.createHealingActions(incidents);
|
|
49
|
+
// Execute auto-healing if enabled
|
|
50
|
+
let healedCount = 0;
|
|
51
|
+
if (request.autoHeal) {
|
|
52
|
+
healedCount = await this.executeAutoHealing(healingActions);
|
|
53
|
+
}
|
|
54
|
+
// Generate recovery strategies
|
|
55
|
+
const strategies = await this.generateRecoveryStrategies(patterns);
|
|
56
|
+
// Collect system metrics
|
|
57
|
+
const metrics = await this.collectSystemMetrics();
|
|
58
|
+
// Generate recommendations
|
|
59
|
+
const recommendations = await this.generateHealingRecommendations(incidents, patterns, metrics);
|
|
60
|
+
const profile = {
|
|
61
|
+
id: profileId,
|
|
62
|
+
systemName: 'ServiceNow Multi-Agent System',
|
|
63
|
+
assessmentDate: new Date().toISOString(),
|
|
64
|
+
healthScore: this.calculateHealthScore(metrics, incidents),
|
|
65
|
+
incidents,
|
|
66
|
+
healingActions,
|
|
67
|
+
patterns,
|
|
68
|
+
predictions,
|
|
69
|
+
recoveryStrategies: strategies,
|
|
70
|
+
systemMetrics: metrics,
|
|
71
|
+
recommendations,
|
|
72
|
+
metadata: {
|
|
73
|
+
monitoringEnabled: true,
|
|
74
|
+
autoHealingEnabled: request.autoHeal || false,
|
|
75
|
+
learningMode: request.learning || true,
|
|
76
|
+
retentionDays: 90,
|
|
77
|
+
integrations: ['ServiceNow', 'Memory System', 'Monitoring'],
|
|
78
|
+
lastFullScan: new Date().toISOString(),
|
|
79
|
+
nextScheduledScan: new Date(Date.now() + 3600000).toISOString()
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
// Store profile
|
|
83
|
+
this.healingProfiles.set(profileId, profile);
|
|
84
|
+
await this.memory.store(`healing_profile_${profileId}`, profile, 7776000000); // 90 days
|
|
85
|
+
// Update learning engine if enabled
|
|
86
|
+
if (request.learning) {
|
|
87
|
+
await this.learningEngine.learn(incidents, healingActions);
|
|
88
|
+
}
|
|
89
|
+
this.logger.info('✅ Health check completed', {
|
|
90
|
+
profileId,
|
|
91
|
+
healthScore: profile.healthScore,
|
|
92
|
+
incidentsDetected: incidents.length,
|
|
93
|
+
incidentsHealed: healedCount,
|
|
94
|
+
predictionsGenerated: predictions.length
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
profile,
|
|
99
|
+
incidentsDetected: incidents.length,
|
|
100
|
+
incidentsHealed: healedCount,
|
|
101
|
+
predictionsGenerated: predictions.length,
|
|
102
|
+
recommendations: recommendations.map(r => r.title),
|
|
103
|
+
warnings: this.generateWarnings(profile)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
this.logger.error('❌ Health check failed', error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Start autonomous self-healing
|
|
113
|
+
*/
|
|
114
|
+
async startAutonomousHealing(options = {}) {
|
|
115
|
+
this.logger.info('🤖 Starting autonomous self-healing', options);
|
|
116
|
+
const interval = options.checkInterval || 300000; // Default: 5 minutes
|
|
117
|
+
const threshold = options.healingThreshold || 0.8; // 80% confidence
|
|
118
|
+
setInterval(async () => {
|
|
119
|
+
try {
|
|
120
|
+
// Perform incremental health check
|
|
121
|
+
const result = await this.performHealthCheck({
|
|
122
|
+
scope: 'incremental',
|
|
123
|
+
autoHeal: true,
|
|
124
|
+
predictive: options.preventive || true,
|
|
125
|
+
learning: true
|
|
126
|
+
});
|
|
127
|
+
// Handle critical incidents
|
|
128
|
+
const criticalIncidents = result.profile.incidents.filter(i => i.severity === 'critical' && i.status === 'active');
|
|
129
|
+
if (criticalIncidents.length > 0) {
|
|
130
|
+
await this.handleCriticalIncidents(criticalIncidents);
|
|
131
|
+
}
|
|
132
|
+
// Execute preventive actions
|
|
133
|
+
if (options.preventive) {
|
|
134
|
+
await this.executePreventiveActions(result.profile.predictions);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.logger.error('Error in autonomous healing', error);
|
|
139
|
+
// Self-heal the self-healing system
|
|
140
|
+
await this.healSelf(error);
|
|
141
|
+
}
|
|
142
|
+
}, interval);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get real-time health dashboard
|
|
146
|
+
*/
|
|
147
|
+
async getHealthDashboard() {
|
|
148
|
+
const latestProfile = this.getLatestHealingProfile();
|
|
149
|
+
if (!latestProfile) {
|
|
150
|
+
const result = await this.performHealthCheck();
|
|
151
|
+
return this.generateDashboard(result.profile);
|
|
152
|
+
}
|
|
153
|
+
return this.generateDashboard(latestProfile);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Manually trigger healing action
|
|
157
|
+
*/
|
|
158
|
+
async executeHealingAction(actionId, options = {}) {
|
|
159
|
+
this.logger.info('💊 Executing healing action', { actionId, options });
|
|
160
|
+
const action = await this.getHealingAction(actionId);
|
|
161
|
+
if (!action) {
|
|
162
|
+
throw new Error(`Healing action not found: ${actionId}`);
|
|
163
|
+
}
|
|
164
|
+
const startTime = Date.now();
|
|
165
|
+
try {
|
|
166
|
+
// Verify if requested
|
|
167
|
+
if (options.verify) {
|
|
168
|
+
const verification = await this.verifyHealingSafety(action);
|
|
169
|
+
if (!verification.safe) {
|
|
170
|
+
throw new Error(`Healing verification failed: ${verification.reason}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Execute healing steps
|
|
174
|
+
action.status = 'executing';
|
|
175
|
+
action.startTime = new Date().toISOString();
|
|
176
|
+
const result = await this.executeHealingSteps(action);
|
|
177
|
+
// Monitor if requested
|
|
178
|
+
if (options.monitor) {
|
|
179
|
+
await this.monitorHealingProgress(action, result);
|
|
180
|
+
}
|
|
181
|
+
// Handle failure with rollback
|
|
182
|
+
if (!result.success && options.rollbackOnFailure) {
|
|
183
|
+
await this.rollbackHealing(action);
|
|
184
|
+
throw new Error(`Healing failed and was rolled back: ${result.message}`);
|
|
185
|
+
}
|
|
186
|
+
// Update action status
|
|
187
|
+
action.status = result.success ? 'completed' : 'failed';
|
|
188
|
+
action.endTime = new Date().toISOString();
|
|
189
|
+
action.result = result;
|
|
190
|
+
const duration = Date.now() - startTime;
|
|
191
|
+
return {
|
|
192
|
+
success: result.success,
|
|
193
|
+
result,
|
|
194
|
+
duration
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
this.logger.error('❌ Healing action failed', error);
|
|
199
|
+
action.status = 'failed';
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Private helper methods
|
|
205
|
+
*/
|
|
206
|
+
initializeRecoveryStrategies() {
|
|
207
|
+
// Initialize common recovery strategies
|
|
208
|
+
this.recoveryStrategies.set('restart_service', {
|
|
209
|
+
id: 'restart_service',
|
|
210
|
+
name: 'Service Restart',
|
|
211
|
+
description: 'Restart affected service to clear transient errors',
|
|
212
|
+
applicableTo: ['error', 'performance'],
|
|
213
|
+
steps: [
|
|
214
|
+
{
|
|
215
|
+
order: 1,
|
|
216
|
+
action: 'Gracefully stop service',
|
|
217
|
+
automated: true,
|
|
218
|
+
timeout: 30000,
|
|
219
|
+
verification: 'Service stopped',
|
|
220
|
+
fallback: 'Force stop service'
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
order: 2,
|
|
224
|
+
action: 'Clear temporary data',
|
|
225
|
+
automated: true,
|
|
226
|
+
timeout: 10000,
|
|
227
|
+
verification: 'Temp data cleared'
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
order: 3,
|
|
231
|
+
action: 'Start service',
|
|
232
|
+
automated: true,
|
|
233
|
+
timeout: 60000,
|
|
234
|
+
verification: 'Service healthy'
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
estimatedTime: 120000,
|
|
238
|
+
successRate: 85,
|
|
239
|
+
requirements: ['Service control permissions'],
|
|
240
|
+
risks: ['Brief downtime']
|
|
241
|
+
});
|
|
242
|
+
this.recoveryStrategies.set('rollback_deployment', {
|
|
243
|
+
id: 'rollback_deployment',
|
|
244
|
+
name: 'Deployment Rollback',
|
|
245
|
+
description: 'Rollback to previous stable version',
|
|
246
|
+
applicableTo: ['error', 'availability'],
|
|
247
|
+
steps: [
|
|
248
|
+
{
|
|
249
|
+
order: 1,
|
|
250
|
+
action: 'Identify rollback point',
|
|
251
|
+
automated: true,
|
|
252
|
+
timeout: 5000,
|
|
253
|
+
verification: 'Rollback point valid'
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
order: 2,
|
|
257
|
+
action: 'Execute rollback',
|
|
258
|
+
automated: true,
|
|
259
|
+
timeout: 300000,
|
|
260
|
+
verification: 'Rollback completed'
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
order: 3,
|
|
264
|
+
action: 'Verify system stability',
|
|
265
|
+
automated: true,
|
|
266
|
+
timeout: 60000,
|
|
267
|
+
verification: 'System stable'
|
|
268
|
+
}
|
|
269
|
+
],
|
|
270
|
+
estimatedTime: 600000,
|
|
271
|
+
successRate: 95,
|
|
272
|
+
requirements: ['Rollback points available'],
|
|
273
|
+
risks: ['Feature regression']
|
|
274
|
+
});
|
|
275
|
+
this.recoveryStrategies.set('scale_resources', {
|
|
276
|
+
id: 'scale_resources',
|
|
277
|
+
name: 'Resource Scaling',
|
|
278
|
+
description: 'Scale up resources to handle load',
|
|
279
|
+
applicableTo: ['performance', 'availability'],
|
|
280
|
+
steps: [
|
|
281
|
+
{
|
|
282
|
+
order: 1,
|
|
283
|
+
action: 'Analyze resource usage',
|
|
284
|
+
automated: true,
|
|
285
|
+
timeout: 10000,
|
|
286
|
+
verification: 'Bottleneck identified'
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
order: 2,
|
|
290
|
+
action: 'Scale resources',
|
|
291
|
+
automated: true,
|
|
292
|
+
timeout: 120000,
|
|
293
|
+
verification: 'Resources scaled'
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
order: 3,
|
|
297
|
+
action: 'Load balance traffic',
|
|
298
|
+
automated: true,
|
|
299
|
+
timeout: 30000,
|
|
300
|
+
verification: 'Traffic balanced'
|
|
301
|
+
}
|
|
302
|
+
],
|
|
303
|
+
estimatedTime: 180000,
|
|
304
|
+
successRate: 90,
|
|
305
|
+
requirements: ['Scaling capability'],
|
|
306
|
+
risks: ['Increased costs']
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
async detectHealthIncidents(request) {
|
|
310
|
+
const incidents = [];
|
|
311
|
+
// Check system logs for errors
|
|
312
|
+
const errorLogs = await this.checkErrorLogs();
|
|
313
|
+
for (const error of errorLogs) {
|
|
314
|
+
incidents.push({
|
|
315
|
+
id: `inc_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
316
|
+
type: 'error',
|
|
317
|
+
severity: this.determineSeverity(error),
|
|
318
|
+
title: error.message,
|
|
319
|
+
description: error.stack || error.message,
|
|
320
|
+
detectedAt: new Date().toISOString(),
|
|
321
|
+
status: 'active',
|
|
322
|
+
impact: {
|
|
323
|
+
users: error.affectedUsers || 0,
|
|
324
|
+
services: error.affectedServices || [],
|
|
325
|
+
availability: 100,
|
|
326
|
+
performance: 0,
|
|
327
|
+
dataLoss: false,
|
|
328
|
+
duration: 0
|
|
329
|
+
},
|
|
330
|
+
healingAttempts: 0
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// Check performance metrics
|
|
334
|
+
const perfIssues = await this.checkPerformanceMetrics();
|
|
335
|
+
for (const issue of perfIssues) {
|
|
336
|
+
incidents.push({
|
|
337
|
+
id: `inc_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
338
|
+
type: 'performance',
|
|
339
|
+
severity: issue.severity,
|
|
340
|
+
title: `Performance degradation in ${issue.service}`,
|
|
341
|
+
description: `Response time increased by ${issue.degradation}%`,
|
|
342
|
+
detectedAt: new Date().toISOString(),
|
|
343
|
+
status: 'active',
|
|
344
|
+
impact: {
|
|
345
|
+
users: issue.affectedUsers,
|
|
346
|
+
services: [issue.service],
|
|
347
|
+
availability: 100,
|
|
348
|
+
performance: issue.degradation,
|
|
349
|
+
dataLoss: false,
|
|
350
|
+
duration: issue.duration
|
|
351
|
+
},
|
|
352
|
+
healingAttempts: 0
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
// Check availability
|
|
356
|
+
const availabilityIssues = await this.checkAvailability();
|
|
357
|
+
for (const issue of availabilityIssues) {
|
|
358
|
+
incidents.push({
|
|
359
|
+
id: `inc_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
360
|
+
type: 'availability',
|
|
361
|
+
severity: 'critical',
|
|
362
|
+
title: `Service unavailable: ${issue.service}`,
|
|
363
|
+
description: issue.reason,
|
|
364
|
+
detectedAt: new Date().toISOString(),
|
|
365
|
+
status: 'active',
|
|
366
|
+
impact: {
|
|
367
|
+
users: issue.affectedUsers,
|
|
368
|
+
services: [issue.service],
|
|
369
|
+
availability: 0,
|
|
370
|
+
performance: 100,
|
|
371
|
+
dataLoss: false,
|
|
372
|
+
duration: issue.downtime
|
|
373
|
+
},
|
|
374
|
+
healingAttempts: 0
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
return incidents;
|
|
378
|
+
}
|
|
379
|
+
async analyzeRootCause(incident) {
|
|
380
|
+
// AI-powered root cause analysis
|
|
381
|
+
const relatedLogs = await this.getRelatedLogs(incident);
|
|
382
|
+
const systemState = await this.getSystemStateAt(incident.detectedAt);
|
|
383
|
+
// Analyze patterns
|
|
384
|
+
const category = this.categorizeRootCause(incident, relatedLogs);
|
|
385
|
+
const confidence = this.calculateConfidence(relatedLogs, systemState);
|
|
386
|
+
return {
|
|
387
|
+
id: `rc_${Date.now()}`,
|
|
388
|
+
category,
|
|
389
|
+
description: this.generateRootCauseDescription(incident, category, relatedLogs),
|
|
390
|
+
confidence,
|
|
391
|
+
evidence: relatedLogs.map(l => l.message),
|
|
392
|
+
relatedIncidents: await this.findRelatedIncidents(incident),
|
|
393
|
+
preventable: confidence > 0.7
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
async identifyErrorPatterns(incidents) {
|
|
397
|
+
const patterns = [];
|
|
398
|
+
// Group incidents by similarity
|
|
399
|
+
const groups = this.groupIncidentsBySimilarity(incidents);
|
|
400
|
+
for (const group of groups) {
|
|
401
|
+
if (group.length >= 2) { // Pattern requires at least 2 occurrences
|
|
402
|
+
const pattern = {
|
|
403
|
+
id: `pat_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
404
|
+
name: this.generatePatternName(group),
|
|
405
|
+
description: this.generatePatternDescription(group),
|
|
406
|
+
signature: {
|
|
407
|
+
errorTypes: [...new Set(group.map(i => i.type))],
|
|
408
|
+
keywords: this.extractKeywords(group),
|
|
409
|
+
frequency: this.determineFrequency(group),
|
|
410
|
+
correlations: this.findCorrelations(group)
|
|
411
|
+
},
|
|
412
|
+
occurrences: group.length,
|
|
413
|
+
lastSeen: group[group.length - 1].detectedAt,
|
|
414
|
+
avgResolutionTime: this.calculateAvgResolutionTime(group),
|
|
415
|
+
successRate: this.calculateSuccessRate(group),
|
|
416
|
+
recommendedActions: this.getRecommendedActions(group),
|
|
417
|
+
autoHealable: this.isAutoHealable(group)
|
|
418
|
+
};
|
|
419
|
+
patterns.push(pattern);
|
|
420
|
+
this.errorPatterns.set(pattern.id, pattern);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return patterns;
|
|
424
|
+
}
|
|
425
|
+
async generateHealthPredictions(incidents, patterns) {
|
|
426
|
+
const predictions = [];
|
|
427
|
+
// Analyze trends
|
|
428
|
+
const trends = await this.analyzeTrends(incidents, patterns);
|
|
429
|
+
// Capacity predictions
|
|
430
|
+
const capacityIssues = await this.predictCapacityIssues();
|
|
431
|
+
for (const issue of capacityIssues) {
|
|
432
|
+
predictions.push({
|
|
433
|
+
id: `pred_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
434
|
+
type: 'capacity',
|
|
435
|
+
component: issue.component,
|
|
436
|
+
probability: issue.probability,
|
|
437
|
+
timeframe: issue.timeframe,
|
|
438
|
+
impact: issue.impact,
|
|
439
|
+
preventiveActions: [
|
|
440
|
+
{
|
|
441
|
+
action: `Scale ${issue.component} capacity`,
|
|
442
|
+
priority: issue.probability > 0.8 ? 'immediate' : 'high',
|
|
443
|
+
estimatedPrevention: 90,
|
|
444
|
+
cost: 'moderate',
|
|
445
|
+
automatable: true
|
|
446
|
+
}
|
|
447
|
+
],
|
|
448
|
+
confidence: issue.confidence,
|
|
449
|
+
basedOn: ['Historical usage patterns', 'Current growth rate']
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
// Failure predictions based on patterns
|
|
453
|
+
for (const pattern of patterns) {
|
|
454
|
+
if (pattern.frequency === 'recurring' || pattern.frequency === 'persistent') {
|
|
455
|
+
const nextOccurrence = this.predictNextOccurrence(pattern);
|
|
456
|
+
if (nextOccurrence.probability > 0.6) {
|
|
457
|
+
predictions.push({
|
|
458
|
+
id: `pred_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
459
|
+
type: 'failure',
|
|
460
|
+
component: 'System',
|
|
461
|
+
probability: nextOccurrence.probability,
|
|
462
|
+
timeframe: nextOccurrence.timeframe,
|
|
463
|
+
impact: 'high',
|
|
464
|
+
preventiveActions: pattern.recommendedActions.map(action => ({
|
|
465
|
+
action,
|
|
466
|
+
priority: 'high',
|
|
467
|
+
estimatedPrevention: 80,
|
|
468
|
+
cost: 'minimal',
|
|
469
|
+
automatable: pattern.autoHealable
|
|
470
|
+
})),
|
|
471
|
+
confidence: 0.85,
|
|
472
|
+
basedOn: [`Pattern: ${pattern.name}`, `${pattern.occurrences} previous occurrences`]
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return predictions;
|
|
478
|
+
}
|
|
479
|
+
async createHealingActions(incidents) {
|
|
480
|
+
const actions = [];
|
|
481
|
+
for (const incident of incidents) {
|
|
482
|
+
// Find matching recovery strategy
|
|
483
|
+
const strategy = this.findBestStrategy(incident);
|
|
484
|
+
if (!strategy)
|
|
485
|
+
continue;
|
|
486
|
+
const action = {
|
|
487
|
+
id: `heal_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
488
|
+
incidentId: incident.id,
|
|
489
|
+
type: this.determineActionType(incident, strategy),
|
|
490
|
+
title: `Heal: ${incident.title}`,
|
|
491
|
+
description: `Apply ${strategy.name} to resolve ${incident.type} issue`,
|
|
492
|
+
status: 'pending',
|
|
493
|
+
automated: strategy.steps.every(s => s.automated),
|
|
494
|
+
executionSteps: strategy.steps.map(s => ({
|
|
495
|
+
order: s.order,
|
|
496
|
+
action: s.action,
|
|
497
|
+
target: incident.impact.services[0] || 'System',
|
|
498
|
+
parameters: {},
|
|
499
|
+
status: 'pending'
|
|
500
|
+
})),
|
|
501
|
+
rollbackPlan: 'Restore from pre-healing snapshot'
|
|
502
|
+
};
|
|
503
|
+
actions.push(action);
|
|
504
|
+
incident.healingAttempts++;
|
|
505
|
+
}
|
|
506
|
+
return actions;
|
|
507
|
+
}
|
|
508
|
+
async executeAutoHealing(actions) {
|
|
509
|
+
let healedCount = 0;
|
|
510
|
+
for (const action of actions) {
|
|
511
|
+
if (action.automated && action.status === 'pending') {
|
|
512
|
+
try {
|
|
513
|
+
const result = await this.executeHealingSteps(action);
|
|
514
|
+
if (result.success) {
|
|
515
|
+
action.status = 'completed';
|
|
516
|
+
healedCount++;
|
|
517
|
+
// Update incident status
|
|
518
|
+
const incident = this.activeIncidents.get(action.incidentId);
|
|
519
|
+
if (incident) {
|
|
520
|
+
incident.status = 'resolved';
|
|
521
|
+
incident.resolvedAt = new Date().toISOString();
|
|
522
|
+
incident.resolutionMethod = action.type;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
this.logger.error(`Failed to auto-heal action ${action.id}`, error);
|
|
528
|
+
action.status = 'failed';
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return healedCount;
|
|
533
|
+
}
|
|
534
|
+
async executeHealingSteps(action) {
|
|
535
|
+
const metricsBefor = await this.captureMetrics();
|
|
536
|
+
const sideEffects = [];
|
|
537
|
+
try {
|
|
538
|
+
for (const step of action.executionSteps) {
|
|
539
|
+
step.status = 'executing';
|
|
540
|
+
// Execute step based on action
|
|
541
|
+
switch (step.action) {
|
|
542
|
+
case 'Gracefully stop service':
|
|
543
|
+
await this.stopService(step.target);
|
|
544
|
+
step.output = 'Service stopped successfully';
|
|
545
|
+
break;
|
|
546
|
+
case 'Clear temporary data':
|
|
547
|
+
await this.clearTempData(step.target);
|
|
548
|
+
step.output = 'Temporary data cleared';
|
|
549
|
+
break;
|
|
550
|
+
case 'Start service':
|
|
551
|
+
await this.startService(step.target);
|
|
552
|
+
step.output = 'Service started successfully';
|
|
553
|
+
break;
|
|
554
|
+
default:
|
|
555
|
+
// Simulate other healing actions
|
|
556
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
557
|
+
step.output = `${step.action} completed`;
|
|
558
|
+
}
|
|
559
|
+
step.status = 'completed';
|
|
560
|
+
step.duration = 1000; // Simulated duration
|
|
561
|
+
}
|
|
562
|
+
const metricsAfter = await this.captureMetrics();
|
|
563
|
+
return {
|
|
564
|
+
success: true,
|
|
565
|
+
message: 'Healing completed successfully',
|
|
566
|
+
metricsAfter: {
|
|
567
|
+
availability: metricsAfter.availability,
|
|
568
|
+
performance: metricsAfter.performance,
|
|
569
|
+
errorRate: metricsAfter.errorRate
|
|
570
|
+
},
|
|
571
|
+
sideEffects,
|
|
572
|
+
verificationPassed: true
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
catch (error) {
|
|
576
|
+
return {
|
|
577
|
+
success: false,
|
|
578
|
+
message: `Healing failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
579
|
+
metricsAfter: metricsBefor,
|
|
580
|
+
sideEffects,
|
|
581
|
+
verificationPassed: false
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async generateRecoveryStrategies(patterns) {
|
|
586
|
+
const strategies = Array.from(this.recoveryStrategies.values());
|
|
587
|
+
// Generate pattern-specific strategies
|
|
588
|
+
for (const pattern of patterns) {
|
|
589
|
+
if (pattern.autoHealable) {
|
|
590
|
+
const customStrategy = {
|
|
591
|
+
id: `strat_${pattern.id}`,
|
|
592
|
+
name: `Auto-heal ${pattern.name}`,
|
|
593
|
+
description: `Automated recovery for ${pattern.description}`,
|
|
594
|
+
applicableTo: pattern.signature.errorTypes,
|
|
595
|
+
steps: this.generateCustomSteps(pattern),
|
|
596
|
+
estimatedTime: pattern.avgResolutionTime,
|
|
597
|
+
successRate: pattern.successRate,
|
|
598
|
+
requirements: [],
|
|
599
|
+
risks: []
|
|
600
|
+
};
|
|
601
|
+
strategies.push(customStrategy);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return strategies;
|
|
605
|
+
}
|
|
606
|
+
async collectSystemMetrics() {
|
|
607
|
+
// Collect real-time system metrics
|
|
608
|
+
return {
|
|
609
|
+
availability: {
|
|
610
|
+
current: 99.5,
|
|
611
|
+
target: 99.9,
|
|
612
|
+
trend: 'stable'
|
|
613
|
+
},
|
|
614
|
+
performance: {
|
|
615
|
+
responseTime: 250, // ms
|
|
616
|
+
throughput: 1000, // requests/sec
|
|
617
|
+
errorRate: 0.5, // percentage
|
|
618
|
+
trend: 'improving'
|
|
619
|
+
},
|
|
620
|
+
reliability: {
|
|
621
|
+
mtbf: 720, // hours
|
|
622
|
+
mttr: 15, // minutes
|
|
623
|
+
failureRate: 0.14 // failures per day
|
|
624
|
+
},
|
|
625
|
+
capacity: {
|
|
626
|
+
cpu: 45, // percentage
|
|
627
|
+
memory: 60,
|
|
628
|
+
storage: 35,
|
|
629
|
+
network: 20
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
async generateHealingRecommendations(incidents, patterns, metrics) {
|
|
634
|
+
const recommendations = [];
|
|
635
|
+
// Redundancy recommendations
|
|
636
|
+
if (metrics.availability.current < metrics.availability.target) {
|
|
637
|
+
recommendations.push({
|
|
638
|
+
id: `rec_${Date.now()}_1`,
|
|
639
|
+
category: 'redundancy',
|
|
640
|
+
priority: 'high',
|
|
641
|
+
title: 'Implement Service Redundancy',
|
|
642
|
+
description: 'Add redundant instances to improve availability',
|
|
643
|
+
benefit: 'Increase availability to target 99.9%',
|
|
644
|
+
effort: 'moderate',
|
|
645
|
+
preventedIncidents: Math.round(incidents.filter(i => i.type === 'availability').length * 0.8),
|
|
646
|
+
roi: 250
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
// Monitoring recommendations
|
|
650
|
+
if (patterns.some(p => p.autoHealable && p.successRate < 80)) {
|
|
651
|
+
recommendations.push({
|
|
652
|
+
id: `rec_${Date.now()}_2`,
|
|
653
|
+
category: 'monitoring',
|
|
654
|
+
priority: 'medium',
|
|
655
|
+
title: 'Enhanced Monitoring Coverage',
|
|
656
|
+
description: 'Improve monitoring to detect issues earlier',
|
|
657
|
+
benefit: 'Reduce MTTR by 50%',
|
|
658
|
+
effort: 'minimal',
|
|
659
|
+
preventedIncidents: Math.round(incidents.length * 0.3),
|
|
660
|
+
roi: 400
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
// Automation recommendations
|
|
664
|
+
const manualActions = incidents.filter(i => !patterns.find(p => p.signature.errorTypes.includes(i.type))?.autoHealable);
|
|
665
|
+
if (manualActions.length > 0) {
|
|
666
|
+
recommendations.push({
|
|
667
|
+
id: `rec_${Date.now()}_3`,
|
|
668
|
+
category: 'automation',
|
|
669
|
+
priority: 'medium',
|
|
670
|
+
title: 'Automate Manual Recovery Processes',
|
|
671
|
+
description: `Automate recovery for ${manualActions.length} manual processes`,
|
|
672
|
+
benefit: 'Reduce recovery time by 80%',
|
|
673
|
+
effort: 'significant',
|
|
674
|
+
preventedIncidents: manualActions.length,
|
|
675
|
+
roi: 300
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
return recommendations;
|
|
679
|
+
}
|
|
680
|
+
calculateHealthScore(metrics, incidents) {
|
|
681
|
+
let score = 100;
|
|
682
|
+
// Availability impact (40% weight)
|
|
683
|
+
const availabilityScore = (metrics.availability.current / metrics.availability.target) * 40;
|
|
684
|
+
score = Math.min(score, availabilityScore + 60);
|
|
685
|
+
// Performance impact (30% weight)
|
|
686
|
+
const performanceScore = Math.max(0, 30 - (metrics.performance.errorRate * 6));
|
|
687
|
+
score = Math.min(score, availabilityScore + performanceScore + 30);
|
|
688
|
+
// Active incidents impact (30% weight)
|
|
689
|
+
const activeIncidents = incidents.filter(i => i.status === 'active');
|
|
690
|
+
const incidentImpact = activeIncidents.reduce((sum, i) => {
|
|
691
|
+
const severityWeight = { critical: 10, high: 5, medium: 2, low: 1 };
|
|
692
|
+
return sum + severityWeight[i.severity];
|
|
693
|
+
}, 0);
|
|
694
|
+
const incidentScore = Math.max(0, 30 - incidentImpact);
|
|
695
|
+
return Math.round(availabilityScore + performanceScore + incidentScore);
|
|
696
|
+
}
|
|
697
|
+
async handleCriticalIncidents(incidents) {
|
|
698
|
+
this.logger.error(`🚨 Handling ${incidents.length} critical incidents`);
|
|
699
|
+
for (const incident of incidents) {
|
|
700
|
+
// Create emergency healing action
|
|
701
|
+
const emergencyAction = {
|
|
702
|
+
id: `emergency_${Date.now()}`,
|
|
703
|
+
incidentId: incident.id,
|
|
704
|
+
type: 'restart',
|
|
705
|
+
title: `Emergency: ${incident.title}`,
|
|
706
|
+
description: 'Emergency healing for critical incident',
|
|
707
|
+
status: 'executing',
|
|
708
|
+
automated: true,
|
|
709
|
+
executionSteps: [
|
|
710
|
+
{
|
|
711
|
+
order: 1,
|
|
712
|
+
action: 'Isolate affected component',
|
|
713
|
+
target: incident.impact.services[0] || 'System',
|
|
714
|
+
parameters: {},
|
|
715
|
+
status: 'pending'
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
order: 2,
|
|
719
|
+
action: 'Apply emergency fix',
|
|
720
|
+
target: incident.impact.services[0] || 'System',
|
|
721
|
+
parameters: {},
|
|
722
|
+
status: 'pending'
|
|
723
|
+
}
|
|
724
|
+
]
|
|
725
|
+
};
|
|
726
|
+
await this.executeHealingSteps(emergencyAction);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
async executePreventiveActions(predictions) {
|
|
730
|
+
for (const prediction of predictions) {
|
|
731
|
+
if (prediction.probability > 0.8 && prediction.impact === 'critical') {
|
|
732
|
+
for (const action of prediction.preventiveActions) {
|
|
733
|
+
if (action.priority === 'immediate' && action.automatable) {
|
|
734
|
+
this.logger.info(`Executing preventive action: ${action.action}`);
|
|
735
|
+
// Execute preventive action
|
|
736
|
+
await this.executePreventiveAction(action);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
async healSelf(error) {
|
|
743
|
+
this.logger.warn('🏥 Self-healing the healing system', error);
|
|
744
|
+
// Restart monitoring
|
|
745
|
+
this.monitoringActive = false;
|
|
746
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
747
|
+
this.monitoringActive = true;
|
|
748
|
+
// Clear error state
|
|
749
|
+
this.activeIncidents.clear();
|
|
750
|
+
// Reinitialize
|
|
751
|
+
this.startHealthMonitoring();
|
|
752
|
+
}
|
|
753
|
+
startHealthMonitoring() {
|
|
754
|
+
if (!this.monitoringActive)
|
|
755
|
+
return;
|
|
756
|
+
// Monitor system health continuously
|
|
757
|
+
setInterval(async () => {
|
|
758
|
+
try {
|
|
759
|
+
await this.checkSystemHealth();
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
this.logger.error('Error in health monitoring', error);
|
|
763
|
+
}
|
|
764
|
+
}, 60000); // Every minute
|
|
765
|
+
}
|
|
766
|
+
async checkSystemHealth() {
|
|
767
|
+
// Quick health check
|
|
768
|
+
const metrics = await this.collectSystemMetrics();
|
|
769
|
+
if (metrics.availability.current < 95) {
|
|
770
|
+
// Create availability incident
|
|
771
|
+
const incident = {
|
|
772
|
+
id: `inc_auto_${Date.now()}`,
|
|
773
|
+
type: 'availability',
|
|
774
|
+
severity: 'high',
|
|
775
|
+
title: 'Low system availability detected',
|
|
776
|
+
description: `Availability dropped to ${metrics.availability.current}%`,
|
|
777
|
+
detectedAt: new Date().toISOString(),
|
|
778
|
+
status: 'active',
|
|
779
|
+
impact: {
|
|
780
|
+
users: 1000,
|
|
781
|
+
services: ['All'],
|
|
782
|
+
availability: metrics.availability.current,
|
|
783
|
+
performance: 0,
|
|
784
|
+
dataLoss: false,
|
|
785
|
+
duration: 0
|
|
786
|
+
},
|
|
787
|
+
healingAttempts: 0
|
|
788
|
+
};
|
|
789
|
+
this.activeIncidents.set(incident.id, incident);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
// Utility methods
|
|
793
|
+
getLatestHealingProfile() {
|
|
794
|
+
const profiles = Array.from(this.healingProfiles.values());
|
|
795
|
+
if (profiles.length === 0)
|
|
796
|
+
return null;
|
|
797
|
+
return profiles.sort((a, b) => new Date(b.assessmentDate).getTime() -
|
|
798
|
+
new Date(a.assessmentDate).getTime())[0];
|
|
799
|
+
}
|
|
800
|
+
async generateDashboard(profile) {
|
|
801
|
+
return {
|
|
802
|
+
systemHealth: profile.healthScore >= 90 ? 'Healthy' :
|
|
803
|
+
profile.healthScore >= 70 ? 'Degraded' : 'Critical',
|
|
804
|
+
healthScore: profile.healthScore,
|
|
805
|
+
activeIncidents: profile.incidents.filter(i => i.status === 'active'),
|
|
806
|
+
recentHealing: profile.healingActions.slice(0, 5),
|
|
807
|
+
systemMetrics: profile.systemMetrics,
|
|
808
|
+
predictions: profile.predictions.filter(p => p.probability > 0.6),
|
|
809
|
+
recommendations: profile.recommendations.slice(0, 3)
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
generateWarnings(profile) {
|
|
813
|
+
const warnings = [];
|
|
814
|
+
const criticalIncidents = profile.incidents.filter(i => i.severity === 'critical' && i.status === 'active');
|
|
815
|
+
if (criticalIncidents.length > 0) {
|
|
816
|
+
warnings.push(`${criticalIncidents.length} critical incidents require immediate attention`);
|
|
817
|
+
}
|
|
818
|
+
if (profile.systemMetrics.availability.current < 99) {
|
|
819
|
+
warnings.push('System availability below target threshold');
|
|
820
|
+
}
|
|
821
|
+
return warnings;
|
|
822
|
+
}
|
|
823
|
+
async checkErrorLogs() {
|
|
824
|
+
// Simulate error log checking
|
|
825
|
+
return [];
|
|
826
|
+
}
|
|
827
|
+
async checkPerformanceMetrics() {
|
|
828
|
+
// Simulate performance checking
|
|
829
|
+
return [];
|
|
830
|
+
}
|
|
831
|
+
async checkAvailability() {
|
|
832
|
+
// Simulate availability checking
|
|
833
|
+
return [];
|
|
834
|
+
}
|
|
835
|
+
determineSeverity(error) {
|
|
836
|
+
if (error.message.includes('CRITICAL') || error.message.includes('FATAL'))
|
|
837
|
+
return 'critical';
|
|
838
|
+
if (error.message.includes('ERROR'))
|
|
839
|
+
return 'high';
|
|
840
|
+
if (error.message.includes('WARNING'))
|
|
841
|
+
return 'medium';
|
|
842
|
+
return 'low';
|
|
843
|
+
}
|
|
844
|
+
async getRelatedLogs(incident) {
|
|
845
|
+
return [];
|
|
846
|
+
}
|
|
847
|
+
async getSystemStateAt(timestamp) {
|
|
848
|
+
return {};
|
|
849
|
+
}
|
|
850
|
+
categorizeRootCause(incident, logs) {
|
|
851
|
+
// Simple categorization logic
|
|
852
|
+
if (incident.type === 'performance')
|
|
853
|
+
return 'resource';
|
|
854
|
+
if (incident.type === 'availability')
|
|
855
|
+
return 'network';
|
|
856
|
+
return 'code';
|
|
857
|
+
}
|
|
858
|
+
calculateConfidence(logs, state) {
|
|
859
|
+
// Simple confidence calculation
|
|
860
|
+
return 0.75 + (logs.length * 0.05);
|
|
861
|
+
}
|
|
862
|
+
generateRootCauseDescription(incident, category, logs) {
|
|
863
|
+
return `${category} issue detected: ${incident.description}`;
|
|
864
|
+
}
|
|
865
|
+
async findRelatedIncidents(incident) {
|
|
866
|
+
return [];
|
|
867
|
+
}
|
|
868
|
+
groupIncidentsBySimilarity(incidents) {
|
|
869
|
+
// Simple grouping by type
|
|
870
|
+
const groups = {};
|
|
871
|
+
for (const incident of incidents) {
|
|
872
|
+
const key = `${incident.type}_${incident.severity}`;
|
|
873
|
+
if (!groups[key])
|
|
874
|
+
groups[key] = [];
|
|
875
|
+
groups[key].push(incident);
|
|
876
|
+
}
|
|
877
|
+
return Object.values(groups);
|
|
878
|
+
}
|
|
879
|
+
generatePatternName(group) {
|
|
880
|
+
return `${group[0].type} pattern #${Date.now()}`;
|
|
881
|
+
}
|
|
882
|
+
generatePatternDescription(group) {
|
|
883
|
+
return `Recurring ${group[0].type} issue affecting ${group[0].impact.services.join(', ')}`;
|
|
884
|
+
}
|
|
885
|
+
extractKeywords(group) {
|
|
886
|
+
const keywords = new Set();
|
|
887
|
+
for (const incident of group) {
|
|
888
|
+
incident.title.split(' ').forEach(word => keywords.add(word.toLowerCase()));
|
|
889
|
+
}
|
|
890
|
+
return Array.from(keywords);
|
|
891
|
+
}
|
|
892
|
+
determineFrequency(group) {
|
|
893
|
+
if (group.length > 10)
|
|
894
|
+
return 'persistent';
|
|
895
|
+
if (group.length > 3)
|
|
896
|
+
return 'recurring';
|
|
897
|
+
return 'sporadic';
|
|
898
|
+
}
|
|
899
|
+
findCorrelations(group) {
|
|
900
|
+
return [];
|
|
901
|
+
}
|
|
902
|
+
calculateAvgResolutionTime(group) {
|
|
903
|
+
const resolved = group.filter(i => i.resolvedAt);
|
|
904
|
+
if (resolved.length === 0)
|
|
905
|
+
return 300000; // 5 minutes default
|
|
906
|
+
const times = resolved.map(i => new Date(i.resolvedAt).getTime() - new Date(i.detectedAt).getTime());
|
|
907
|
+
return times.reduce((a, b) => a + b, 0) / times.length;
|
|
908
|
+
}
|
|
909
|
+
calculateSuccessRate(group) {
|
|
910
|
+
const resolved = group.filter(i => i.status === 'resolved').length;
|
|
911
|
+
return group.length > 0 ? (resolved / group.length) * 100 : 0;
|
|
912
|
+
}
|
|
913
|
+
getRecommendedActions(group) {
|
|
914
|
+
const actions = [];
|
|
915
|
+
if (group[0].type === 'error')
|
|
916
|
+
actions.push('Apply error handling patch');
|
|
917
|
+
if (group[0].type === 'performance')
|
|
918
|
+
actions.push('Optimize resource allocation');
|
|
919
|
+
if (group[0].type === 'availability')
|
|
920
|
+
actions.push('Implement redundancy');
|
|
921
|
+
return actions;
|
|
922
|
+
}
|
|
923
|
+
isAutoHealable(group) {
|
|
924
|
+
// Check if pattern can be auto-healed
|
|
925
|
+
return group[0].type !== 'security' && this.calculateSuccessRate(group) > 70;
|
|
926
|
+
}
|
|
927
|
+
async analyzeTrends(incidents, patterns) {
|
|
928
|
+
return {};
|
|
929
|
+
}
|
|
930
|
+
async predictCapacityIssues() {
|
|
931
|
+
return [
|
|
932
|
+
{
|
|
933
|
+
component: 'Memory',
|
|
934
|
+
probability: 0.75,
|
|
935
|
+
timeframe: '7 days',
|
|
936
|
+
impact: 'high',
|
|
937
|
+
confidence: 0.85
|
|
938
|
+
}
|
|
939
|
+
];
|
|
940
|
+
}
|
|
941
|
+
predictNextOccurrence(pattern) {
|
|
942
|
+
// Simple prediction based on frequency
|
|
943
|
+
if (pattern.frequency === 'persistent') {
|
|
944
|
+
return { probability: 0.9, timeframe: '1 hour' };
|
|
945
|
+
}
|
|
946
|
+
if (pattern.frequency === 'recurring') {
|
|
947
|
+
return { probability: 0.7, timeframe: '24 hours' };
|
|
948
|
+
}
|
|
949
|
+
return { probability: 0.3, timeframe: '7 days' };
|
|
950
|
+
}
|
|
951
|
+
findBestStrategy(incident) {
|
|
952
|
+
for (const strategy of this.recoveryStrategies.values()) {
|
|
953
|
+
if (strategy.applicableTo.includes(incident.type)) {
|
|
954
|
+
return strategy;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
return null;
|
|
958
|
+
}
|
|
959
|
+
determineActionType(incident, strategy) {
|
|
960
|
+
if (strategy.id === 'restart_service')
|
|
961
|
+
return 'restart';
|
|
962
|
+
if (strategy.id === 'rollback_deployment')
|
|
963
|
+
return 'rollback';
|
|
964
|
+
if (strategy.id === 'scale_resources')
|
|
965
|
+
return 'scale';
|
|
966
|
+
return 'patch';
|
|
967
|
+
}
|
|
968
|
+
async captureMetrics() {
|
|
969
|
+
const metrics = await this.collectSystemMetrics();
|
|
970
|
+
return {
|
|
971
|
+
availability: metrics.availability.current,
|
|
972
|
+
performance: metrics.performance.responseTime,
|
|
973
|
+
errorRate: metrics.performance.errorRate
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
async stopService(target) {
|
|
977
|
+
this.logger.info(`Stopping service: ${target}`);
|
|
978
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
979
|
+
}
|
|
980
|
+
async clearTempData(target) {
|
|
981
|
+
this.logger.info(`Clearing temp data for: ${target}`);
|
|
982
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
983
|
+
}
|
|
984
|
+
async startService(target) {
|
|
985
|
+
this.logger.info(`Starting service: ${target}`);
|
|
986
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
987
|
+
}
|
|
988
|
+
generateCustomSteps(pattern) {
|
|
989
|
+
return pattern.recommendedActions.map((action, index) => ({
|
|
990
|
+
order: index + 1,
|
|
991
|
+
action,
|
|
992
|
+
automated: pattern.autoHealable,
|
|
993
|
+
timeout: 60000,
|
|
994
|
+
verification: 'Action completed successfully'
|
|
995
|
+
}));
|
|
996
|
+
}
|
|
997
|
+
async getHealingAction(actionId) {
|
|
998
|
+
for (const profile of this.healingProfiles.values()) {
|
|
999
|
+
const action = profile.healingActions.find(a => a.id === actionId);
|
|
1000
|
+
if (action)
|
|
1001
|
+
return action;
|
|
1002
|
+
}
|
|
1003
|
+
return null;
|
|
1004
|
+
}
|
|
1005
|
+
async verifyHealingSafety(action) {
|
|
1006
|
+
// Verify it's safe to execute healing
|
|
1007
|
+
if (action.type === 'rollback' && !action.rollbackPlan) {
|
|
1008
|
+
return { safe: false, reason: 'No rollback plan available' };
|
|
1009
|
+
}
|
|
1010
|
+
return { safe: true };
|
|
1011
|
+
}
|
|
1012
|
+
async monitorHealingProgress(action, result) {
|
|
1013
|
+
this.logger.info(`Monitoring healing progress for action ${action.id}`);
|
|
1014
|
+
// Monitor the healing impact
|
|
1015
|
+
}
|
|
1016
|
+
async rollbackHealing(action) {
|
|
1017
|
+
this.logger.warn(`Rolling back healing action ${action.id}`);
|
|
1018
|
+
// Implement rollback logic
|
|
1019
|
+
}
|
|
1020
|
+
async executePreventiveAction(action) {
|
|
1021
|
+
this.logger.info(`Executing preventive action: ${action.action}`);
|
|
1022
|
+
// Execute the preventive action
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
exports.SelfHealingSystem = SelfHealingSystem;
|
|
1026
|
+
// Learning engine for pattern recognition
|
|
1027
|
+
class LearningEngine {
|
|
1028
|
+
constructor(memory) {
|
|
1029
|
+
this.memory = memory;
|
|
1030
|
+
}
|
|
1031
|
+
async learn(incidents, actions) {
|
|
1032
|
+
// Store patterns for future recognition
|
|
1033
|
+
const learningData = {
|
|
1034
|
+
incidents,
|
|
1035
|
+
actions,
|
|
1036
|
+
timestamp: new Date().toISOString()
|
|
1037
|
+
};
|
|
1038
|
+
await this.memory.store('healing_patterns', learningData, 2592000000); // 30 days
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
exports.default = SelfHealingSystem;
|