snow-flow 2.0.2 → 2.0.3
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/mcp-config.json → .mcp.json} +13 -12
- package/.releaserc.json +47 -0
- package/README.md +6 -0
- package/package.json +1 -1
- package/.claude/claude-settings.json +0 -15
- package/.claude/commands/analysis/README.md +0 -9
- package/.claude/commands/automation/README.md +0 -9
- package/.claude/commands/github/README.md +0 -11
- package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
- package/.claude/commands/hooks/README.md +0 -11
- package/.claude/commands/monitoring/README.md +0 -9
- package/.claude/commands/optimization/README.md +0 -9
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/config.json +0 -36
- package/.claude/helpers/github-setup.sh +0 -28
- package/.claude/helpers/quick-start.sh +0 -19
- package/.claude/helpers/setup-mcp.sh +0 -18
- package/.claude/settings.json +0 -114
- package/.claude/settings.local.json +0 -33
- package/.claude-flow/metrics/agent-metrics.json +0 -1
- package/.claude-flow/metrics/performance.json +0 -9
- package/.claude-flow/metrics/system-metrics.json +0 -15986
- package/.claude-flow/metrics/task-metrics.json +0 -10
- package/.roo/README.md +0 -402
- package/.roo/mcp-list.txt +0 -257
- package/.roo/mcp.json +0 -32
- package/.roo/workflows/basic-tdd.json +0 -32
- package/.roomodes +0 -201
- package/CLAUDE.md +0 -393
- package/bin/snow-flow.js +0 -3
- package/dist/cli.js.bak +0 -2052
- package/dist/config/snow-flow-config.d.ts +0 -1492
- package/dist/config/snow-flow-config.js +0 -938
- package/scripts/create-env.js +0 -91
- package/scripts/postinstall.js +0 -30
- package/scripts/register-mcp-servers.js +0 -210
- package/scripts/reset-mcp-servers.js +0 -246
- package/scripts/setup-mcp.js +0 -106
- package/scripts/update-version.js +0 -31
- package/src/agents/README.md +0 -192
- package/src/agents/base-agent.ts +0 -251
- package/src/agents/coordinator.ts +0 -971
- package/src/agents/index.ts +0 -18
- package/src/agents/queen-403-handler.ts +0 -230
- package/src/agents/queen-agent.ts +0 -1399
- package/src/agents/script-writer-agent.ts +0 -769
- package/src/agents/security-agent.ts +0 -726
- package/src/agents/widget-creator-agent.ts +0 -568
- package/src/api/error-handling.ts +0 -1758
- package/src/api/natural-language-mapper.ts +0 -630
- package/src/api/performance-optimizer.ts +0 -891
- package/src/api/transaction-manager.ts +0 -754
- package/src/cli/deploy-artifact.ts +0 -304
- package/src/cli/snow-flow-cli-integration.ts +0 -434
- package/src/cli.ts +0 -4455
- package/src/cli.ts.bak +0 -5616
- package/src/compliance/advanced-compliance-system.ts +0 -1268
- package/src/compliance/index.ts +0 -19
- package/src/config/snow-flow-config.ts +0 -1019
- package/src/documentation/index.ts +0 -16
- package/src/documentation/self-documenting-system.ts +0 -1421
- package/src/dynamic-version.ts +0 -44
- package/src/healing/index.ts +0 -20
- package/src/healing/self-healing-system.ts +0 -1435
- package/src/health/README.md +0 -161
- package/src/health/system-health.ts +0 -995
- package/src/index.ts +0 -60
- package/src/intelligence/acl-analyzer.ts +0 -377
- package/src/intelligence/auto-resolution-engine.ts +0 -643
- package/src/intelligence/gap-analysis-engine.ts +0 -488
- package/src/intelligence/manual-instructions-generator.ts +0 -744
- package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
- package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
- package/src/intelligence/performance-recommendations-engine.ts +0 -1223
- package/src/intelligence/requirements-analyzer.ts +0 -1148
- package/src/intelligence/task-analyzer.ts +0 -628
- package/src/managers/scope-manager.ts +0 -555
- package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
- package/src/mcp/base-mcp-server.ts +0 -660
- package/src/mcp/http-transport-wrapper.ts +0 -426
- package/src/mcp/service-discovery-client.ts +0 -312
- package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
- package/src/mcp/servicenow-automation-mcp.ts +0 -838
- package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
- package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
- package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
- package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
- package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
- package/src/mcp/servicenow-integration-mcp.ts +0 -819
- package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
- package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
- package/src/mcp/servicenow-mcp-server.ts +0 -728
- package/src/mcp/servicenow-memory-mcp.ts +0 -474
- package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
- package/src/mcp/servicenow-operations-mcp.ts +0 -3384
- package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
- package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
- package/src/mcp/servicenow-progressive-indexer.ts +0 -370
- package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
- package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
- package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
- package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
- package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
- package/src/mcp/servicenow-update-set-mcp.ts +0 -811
- package/src/mcp/shared/agent-context-provider.ts +0 -365
- package/src/mcp/shared/base-mcp-server.ts +0 -2463
- package/src/mcp/shared/mcp-memory-manager.ts +0 -540
- package/src/mcp/shared/mcp-resource-manager.ts +0 -367
- package/src/mcp/snow-flow-mcp.ts +0 -911
- package/src/mcp/start-all-mcp-servers.ts +0 -102
- package/src/mcp/start-servicenow-mcp.ts +0 -67
- package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
- package/src/monitoring/performance-tracker.ts +0 -777
- package/src/optimization/cost-optimization-engine.ts +0 -1125
- package/src/optimization/index.ts +0 -10
- package/src/queen/README.md +0 -403
- package/src/queen/agent-factory.ts +0 -574
- package/src/queen/index.ts +0 -94
- package/src/queen/mcp-execution-bridge.ts +0 -681
- package/src/queen/neural-learning.ts +0 -319
- package/src/queen/parallel-agent-engine.ts +0 -848
- package/src/queen/queen-memory-system.ts +0 -490
- package/src/queen/queen-memory.ts +0 -456
- package/src/queen/servicenow-queen.ts +0 -1029
- package/src/queen/types.ts +0 -87
- package/src/rollback/smart-rollback-system.ts +0 -866
- package/src/schemas/deployment.schema.json +0 -58
- package/src/schemas/flow.schema.json +0 -79
- package/src/schemas/widget.schema.json +0 -72
- package/src/snow-flow-system.ts +0 -541
- package/src/sparc/sparc-help.ts +0 -49
- package/src/sparc/team-sparc.ts +0 -88
- package/src/strategies/global-scope-strategy.ts +0 -736
- package/src/templates/base/application.template.json +0 -45
- package/src/templates/base/business_rule.template.json +0 -33
- package/src/templates/base/script_include.template.json +0 -18
- package/src/templates/base/table.template.json +0 -64
- package/src/templates/base/widget.template.json +0 -25
- package/src/templates/patterns/composite.incident-management.template.json +0 -140
- package/src/templates/patterns/widget.dashboard.template.json +0 -238
- package/src/templates/patterns/widget.datatable.template.json +0 -292
- package/src/testing/integration-test-suite.ts +0 -1276
- package/src/types/index.ts +0 -183
- package/src/types/neo4j-driver.d.ts +0 -23
- package/src/types/servicenow.types.ts +0 -307
- package/src/types/snow-flow.types.ts +0 -186
- package/src/types/todo.types.ts +0 -70
- package/src/utils/action-type-cache.ts +0 -286
- package/src/utils/agent-detector.ts +0 -573
- package/src/utils/artifact-tracker.ts +0 -379
- package/src/utils/dependency-detector.ts +0 -233
- package/src/utils/deployment-metadata-handler.ts +0 -518
- package/src/utils/error-recovery.ts +0 -680
- package/src/utils/logger.ts +0 -60
- package/src/utils/mcp-auth-middleware.ts +0 -262
- package/src/utils/mcp-config-manager.ts +0 -270
- package/src/utils/mcp-server-manager.ts +0 -446
- package/src/utils/mcp-tool-registry.ts +0 -298
- package/src/utils/migrate-snow-flow.ts +0 -98
- package/src/utils/oauth-html-templates.ts +0 -188
- package/src/utils/scope-utils.ts +0 -443
- package/src/utils/servicenow-client.ts +0 -3321
- package/src/utils/servicenow-id-generator.ts +0 -181
- package/src/utils/snow-memory-manager.ts +0 -605
- package/src/utils/snow-oauth.ts +0 -797
- package/src/utils/template-engine.ts +0 -463
- package/src/utils/theme-manager.ts +0 -295
- package/src/utils/unified-auth-store.ts +0 -222
- package/src/utils/update-set-importer.ts +0 -422
- package/src/utils/update-set-xml-packager.ts +0 -371
- package/src/utils/widget-template-generator.ts +0 -1744
- package/src/version.ts +0 -1950
|
@@ -1,777 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Snow-Flow Performance Monitoring System
|
|
3
|
-
* Real-time metrics collection and analysis
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { EventEmitter } from 'events';
|
|
7
|
-
import { MemorySystem } from '../memory/memory-system';
|
|
8
|
-
import { Logger } from '../utils/logger';
|
|
9
|
-
|
|
10
|
-
export interface PerformanceMetric {
|
|
11
|
-
id: string;
|
|
12
|
-
operation: string;
|
|
13
|
-
startTime: number;
|
|
14
|
-
endTime?: number;
|
|
15
|
-
duration?: number;
|
|
16
|
-
success: boolean;
|
|
17
|
-
metadata: Record<string, any>;
|
|
18
|
-
sessionId?: string;
|
|
19
|
-
agentId?: string;
|
|
20
|
-
resourceUsage?: ResourceUsage;
|
|
21
|
-
error?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ResourceUsage {
|
|
25
|
-
cpuUsage: number;
|
|
26
|
-
memoryUsage: number;
|
|
27
|
-
heapUsed: number;
|
|
28
|
-
heapTotal: number;
|
|
29
|
-
external: number;
|
|
30
|
-
arrayBuffers: number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface AggregateMetrics {
|
|
34
|
-
operation: string;
|
|
35
|
-
count: number;
|
|
36
|
-
successCount: number;
|
|
37
|
-
failureCount: number;
|
|
38
|
-
averageDuration: number;
|
|
39
|
-
minDuration: number;
|
|
40
|
-
maxDuration: number;
|
|
41
|
-
percentile95: number;
|
|
42
|
-
percentile99: number;
|
|
43
|
-
errorRate: number;
|
|
44
|
-
throughput: number; // operations per second
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface SessionMetrics {
|
|
48
|
-
sessionId: string;
|
|
49
|
-
startTime: Date;
|
|
50
|
-
endTime?: Date;
|
|
51
|
-
duration?: number;
|
|
52
|
-
operationCount: number;
|
|
53
|
-
successCount: number;
|
|
54
|
-
failureCount: number;
|
|
55
|
-
agentCount: number;
|
|
56
|
-
artifactCount: number;
|
|
57
|
-
averageOperationTime: number;
|
|
58
|
-
resourceUsage: ResourceUsage[];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface PerformanceReport {
|
|
62
|
-
timestamp: Date;
|
|
63
|
-
period: string;
|
|
64
|
-
summary: {
|
|
65
|
-
totalOperations: number;
|
|
66
|
-
successRate: number;
|
|
67
|
-
averageResponseTime: number;
|
|
68
|
-
peakConcurrency: number;
|
|
69
|
-
errorRate: number;
|
|
70
|
-
};
|
|
71
|
-
operationMetrics: AggregateMetrics[];
|
|
72
|
-
sessionMetrics: SessionMetrics[];
|
|
73
|
-
bottlenecks: Bottleneck[];
|
|
74
|
-
recommendations: string[];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface Bottleneck {
|
|
78
|
-
operation: string;
|
|
79
|
-
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
80
|
-
impact: string;
|
|
81
|
-
occurrences: number;
|
|
82
|
-
averageDelay: number;
|
|
83
|
-
recommendation: string;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
interface TrackerConfig {
|
|
87
|
-
memory: MemorySystem;
|
|
88
|
-
config: {
|
|
89
|
-
sampleRate: number;
|
|
90
|
-
metricsRetention: number;
|
|
91
|
-
aggregationInterval: number;
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export class PerformanceTracker extends EventEmitter {
|
|
96
|
-
private memory: MemorySystem;
|
|
97
|
-
private logger: Logger;
|
|
98
|
-
private config: TrackerConfig['config'];
|
|
99
|
-
private activeOperations: Map<string, PerformanceMetric> = new Map();
|
|
100
|
-
private metricsBuffer: PerformanceMetric[] = [];
|
|
101
|
-
private aggregationTimer?: NodeJS.Timeout;
|
|
102
|
-
private initialized = false;
|
|
103
|
-
|
|
104
|
-
constructor(options: TrackerConfig) {
|
|
105
|
-
super();
|
|
106
|
-
this.memory = options.memory;
|
|
107
|
-
this.config = options.config;
|
|
108
|
-
this.logger = new Logger('PerformanceTracker');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Initialize the performance tracker
|
|
113
|
-
*/
|
|
114
|
-
async initialize(): Promise<void> {
|
|
115
|
-
if (this.initialized) return;
|
|
116
|
-
|
|
117
|
-
this.logger.info('Initializing Performance Tracker...');
|
|
118
|
-
|
|
119
|
-
// Create performance tables if not exist
|
|
120
|
-
await this.createPerformanceTables();
|
|
121
|
-
|
|
122
|
-
// Start aggregation timer
|
|
123
|
-
this.startAggregation();
|
|
124
|
-
|
|
125
|
-
// Monitor system resources
|
|
126
|
-
this.startResourceMonitoring();
|
|
127
|
-
|
|
128
|
-
this.initialized = true;
|
|
129
|
-
this.logger.info('Performance Tracker initialized');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Start tracking an operation
|
|
134
|
-
*/
|
|
135
|
-
async startOperation(operation: string, metadata: Record<string, any> = {}): Promise<string> {
|
|
136
|
-
// Apply sampling rate
|
|
137
|
-
if (Math.random() > this.config.sampleRate) {
|
|
138
|
-
return 'not_sampled';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const id = this.generateMetricId();
|
|
142
|
-
const metric: PerformanceMetric = {
|
|
143
|
-
id,
|
|
144
|
-
operation,
|
|
145
|
-
startTime: Date.now(),
|
|
146
|
-
success: false,
|
|
147
|
-
metadata,
|
|
148
|
-
sessionId: metadata.sessionId,
|
|
149
|
-
agentId: metadata.agentId,
|
|
150
|
-
resourceUsage: this.captureResourceUsage()
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
this.activeOperations.set(id, metric);
|
|
154
|
-
|
|
155
|
-
// Emit start event
|
|
156
|
-
this.emit('operation:start', {
|
|
157
|
-
id,
|
|
158
|
-
operation,
|
|
159
|
-
metadata
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
return id;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* End tracking an operation
|
|
167
|
-
*/
|
|
168
|
-
async endOperation(operationId: string, result: { success: boolean; error?: string; metadata?: any }): Promise<void> {
|
|
169
|
-
const metric = this.activeOperations.get(operationId);
|
|
170
|
-
if (!metric || operationId === 'not_sampled') return;
|
|
171
|
-
|
|
172
|
-
metric.endTime = Date.now();
|
|
173
|
-
metric.duration = metric.endTime - metric.startTime;
|
|
174
|
-
metric.success = result.success;
|
|
175
|
-
metric.error = result.error;
|
|
176
|
-
|
|
177
|
-
if (result.metadata) {
|
|
178
|
-
Object.assign(metric.metadata, result.metadata);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Capture final resource usage
|
|
182
|
-
const finalResourceUsage = this.captureResourceUsage();
|
|
183
|
-
metric.resourceUsage = this.calculateResourceDelta(metric.resourceUsage!, finalResourceUsage);
|
|
184
|
-
|
|
185
|
-
// Remove from active and add to buffer
|
|
186
|
-
this.activeOperations.delete(operationId);
|
|
187
|
-
this.metricsBuffer.push(metric);
|
|
188
|
-
|
|
189
|
-
// Store immediately if buffer is large
|
|
190
|
-
if (this.metricsBuffer.length >= 100) {
|
|
191
|
-
await this.flushMetrics();
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Emit end event
|
|
195
|
-
this.emit('operation:end', {
|
|
196
|
-
id: operationId,
|
|
197
|
-
operation: metric.operation,
|
|
198
|
-
duration: metric.duration,
|
|
199
|
-
success: metric.success
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Check for performance issues
|
|
203
|
-
this.checkPerformanceThresholds(metric);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Track a complete operation (convenience method)
|
|
208
|
-
*/
|
|
209
|
-
async trackOperation<T>(
|
|
210
|
-
operation: string,
|
|
211
|
-
metadata: Record<string, any>,
|
|
212
|
-
fn: () => Promise<T>
|
|
213
|
-
): Promise<T> {
|
|
214
|
-
const id = await this.startOperation(operation, metadata);
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
const result = await fn();
|
|
218
|
-
await this.endOperation(id, { success: true });
|
|
219
|
-
return result;
|
|
220
|
-
} catch (error) {
|
|
221
|
-
await this.endOperation(id, {
|
|
222
|
-
success: false,
|
|
223
|
-
error: (error as Error).message
|
|
224
|
-
});
|
|
225
|
-
throw error;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Get metrics for a specific session
|
|
231
|
-
*/
|
|
232
|
-
async getSessionMetrics(sessionId: string): Promise<SessionMetrics> {
|
|
233
|
-
const metrics = await this.memory.query<PerformanceMetric>(`
|
|
234
|
-
SELECT * FROM performance_metrics
|
|
235
|
-
WHERE session_id = ?
|
|
236
|
-
ORDER BY start_time
|
|
237
|
-
`, [sessionId]);
|
|
238
|
-
|
|
239
|
-
if (metrics.length === 0) {
|
|
240
|
-
return {
|
|
241
|
-
sessionId,
|
|
242
|
-
startTime: new Date(),
|
|
243
|
-
operationCount: 0,
|
|
244
|
-
successCount: 0,
|
|
245
|
-
failureCount: 0,
|
|
246
|
-
agentCount: 0,
|
|
247
|
-
artifactCount: 0,
|
|
248
|
-
averageOperationTime: 0,
|
|
249
|
-
resourceUsage: []
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const startTime = new Date(metrics[0].startTime);
|
|
254
|
-
const endTime = metrics[metrics.length - 1].endTime ?
|
|
255
|
-
new Date(metrics[metrics.length - 1].endTime!) : undefined;
|
|
256
|
-
|
|
257
|
-
const successCount = metrics.filter(m => m.success).length;
|
|
258
|
-
const totalDuration = metrics.reduce((sum, m) => sum + (m.duration || 0), 0);
|
|
259
|
-
const agentIds = new Set(metrics.map(m => m.agentId).filter(Boolean));
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
sessionId,
|
|
263
|
-
startTime,
|
|
264
|
-
endTime,
|
|
265
|
-
duration: endTime ? endTime.getTime() - startTime.getTime() : undefined,
|
|
266
|
-
operationCount: metrics.length,
|
|
267
|
-
successCount,
|
|
268
|
-
failureCount: metrics.length - successCount,
|
|
269
|
-
agentCount: agentIds.size,
|
|
270
|
-
artifactCount: await this.countSessionArtifacts(sessionId),
|
|
271
|
-
averageOperationTime: metrics.length > 0 ? totalDuration / metrics.length : 0,
|
|
272
|
-
resourceUsage: metrics.map(m => m.resourceUsage).filter(Boolean) as ResourceUsage[]
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Get aggregate metrics for an operation
|
|
278
|
-
*/
|
|
279
|
-
async getAggregateMetrics(operation: string, timeframe?: number): Promise<AggregateMetrics> {
|
|
280
|
-
const since = timeframe ? Date.now() - timeframe : 0;
|
|
281
|
-
|
|
282
|
-
const metrics = await this.memory.query<PerformanceMetric>(`
|
|
283
|
-
SELECT * FROM performance_metrics
|
|
284
|
-
WHERE operation = ? AND start_time > ?
|
|
285
|
-
ORDER BY duration
|
|
286
|
-
`, [operation, since]);
|
|
287
|
-
|
|
288
|
-
if (metrics.length === 0) {
|
|
289
|
-
return {
|
|
290
|
-
operation,
|
|
291
|
-
count: 0,
|
|
292
|
-
successCount: 0,
|
|
293
|
-
failureCount: 0,
|
|
294
|
-
averageDuration: 0,
|
|
295
|
-
minDuration: 0,
|
|
296
|
-
maxDuration: 0,
|
|
297
|
-
percentile95: 0,
|
|
298
|
-
percentile99: 0,
|
|
299
|
-
errorRate: 0,
|
|
300
|
-
throughput: 0
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const successCount = metrics.filter(m => m.success).length;
|
|
305
|
-
const durations = metrics.map(m => m.duration || 0).filter(d => d > 0);
|
|
306
|
-
durations.sort((a, b) => a - b);
|
|
307
|
-
|
|
308
|
-
const timeRange = metrics[metrics.length - 1].startTime - metrics[0].startTime;
|
|
309
|
-
const throughput = timeRange > 0 ? (metrics.length / timeRange) * 1000 : 0;
|
|
310
|
-
|
|
311
|
-
return {
|
|
312
|
-
operation,
|
|
313
|
-
count: metrics.length,
|
|
314
|
-
successCount,
|
|
315
|
-
failureCount: metrics.length - successCount,
|
|
316
|
-
averageDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
|
|
317
|
-
minDuration: durations[0] || 0,
|
|
318
|
-
maxDuration: durations[durations.length - 1] || 0,
|
|
319
|
-
percentile95: this.calculatePercentile(durations, 0.95),
|
|
320
|
-
percentile99: this.calculatePercentile(durations, 0.99),
|
|
321
|
-
errorRate: metrics.length > 0 ? (metrics.length - successCount) / metrics.length : 0,
|
|
322
|
-
throughput
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Generate performance report
|
|
328
|
-
*/
|
|
329
|
-
async generateReport(period: 'hour' | 'day' | 'week' | 'month' = 'day'): Promise<PerformanceReport> {
|
|
330
|
-
const timeframe = this.getTimeframe(period);
|
|
331
|
-
const since = Date.now() - timeframe;
|
|
332
|
-
|
|
333
|
-
// Get all metrics for the period
|
|
334
|
-
const allMetrics = await this.memory.query<PerformanceMetric>(`
|
|
335
|
-
SELECT * FROM performance_metrics
|
|
336
|
-
WHERE start_time > ?
|
|
337
|
-
`, [since]);
|
|
338
|
-
|
|
339
|
-
// Get unique operations
|
|
340
|
-
const operations = [...new Set(allMetrics.map(m => m.operation))];
|
|
341
|
-
|
|
342
|
-
// Calculate operation metrics
|
|
343
|
-
const operationMetrics = await Promise.all(
|
|
344
|
-
operations.map(op => this.getAggregateMetrics(op, timeframe))
|
|
345
|
-
);
|
|
346
|
-
|
|
347
|
-
// Get session metrics
|
|
348
|
-
const sessionIds = [...new Set(allMetrics.map(m => m.sessionId).filter(Boolean))];
|
|
349
|
-
const sessionMetrics = await Promise.all(
|
|
350
|
-
sessionIds.map(id => this.getSessionMetrics(id))
|
|
351
|
-
);
|
|
352
|
-
|
|
353
|
-
// Identify bottlenecks
|
|
354
|
-
const bottlenecks = await this.identifyBottlenecks(allMetrics);
|
|
355
|
-
|
|
356
|
-
// Generate recommendations
|
|
357
|
-
const recommendations = this.generateRecommendations(
|
|
358
|
-
operationMetrics,
|
|
359
|
-
sessionMetrics,
|
|
360
|
-
bottlenecks
|
|
361
|
-
);
|
|
362
|
-
|
|
363
|
-
// Calculate summary
|
|
364
|
-
const totalOperations = allMetrics.length;
|
|
365
|
-
const successCount = allMetrics.filter(m => m.success).length;
|
|
366
|
-
const totalDuration = allMetrics.reduce((sum, m) => sum + (m.duration || 0), 0);
|
|
367
|
-
|
|
368
|
-
const report: PerformanceReport = {
|
|
369
|
-
timestamp: new Date(),
|
|
370
|
-
period,
|
|
371
|
-
summary: {
|
|
372
|
-
totalOperations,
|
|
373
|
-
successRate: totalOperations > 0 ? (successCount / totalOperations) * 100 : 0,
|
|
374
|
-
averageResponseTime: totalOperations > 0 ? totalDuration / totalOperations : 0,
|
|
375
|
-
peakConcurrency: this.calculatePeakConcurrency(allMetrics),
|
|
376
|
-
errorRate: totalOperations > 0 ? ((totalOperations - successCount) / totalOperations) * 100 : 0
|
|
377
|
-
},
|
|
378
|
-
operationMetrics,
|
|
379
|
-
sessionMetrics,
|
|
380
|
-
bottlenecks,
|
|
381
|
-
recommendations
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
// Store report
|
|
385
|
-
await this.memory.store(`performance_report_${period}_${Date.now()}`, report);
|
|
386
|
-
|
|
387
|
-
return report;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Identify performance bottlenecks
|
|
392
|
-
*/
|
|
393
|
-
async identifyBottlenecks(metrics: PerformanceMetric[]): Promise<Bottleneck[]> {
|
|
394
|
-
const bottlenecks: Bottleneck[] = [];
|
|
395
|
-
|
|
396
|
-
// Group by operation
|
|
397
|
-
const operationGroups = this.groupBy(metrics, 'operation');
|
|
398
|
-
|
|
399
|
-
for (const [operation, operationMetrics] of Object.entries(operationGroups)) {
|
|
400
|
-
const durations = operationMetrics.map(m => m.duration || 0);
|
|
401
|
-
const avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
402
|
-
const p95Duration = this.calculatePercentile(durations, 0.95);
|
|
403
|
-
|
|
404
|
-
// Check for slow operations
|
|
405
|
-
if (avgDuration > 5000) { // > 5 seconds average
|
|
406
|
-
bottlenecks.push({
|
|
407
|
-
operation,
|
|
408
|
-
severity: avgDuration > 30000 ? 'critical' : avgDuration > 15000 ? 'high' : 'medium',
|
|
409
|
-
impact: `Average response time of ${(avgDuration / 1000).toFixed(2)}s`,
|
|
410
|
-
occurrences: operationMetrics.length,
|
|
411
|
-
averageDelay: avgDuration - 5000,
|
|
412
|
-
recommendation: 'Optimize operation logic or add caching'
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// Check for high variance
|
|
417
|
-
const variance = this.calculateVariance(durations);
|
|
418
|
-
if (variance > avgDuration * 2) {
|
|
419
|
-
bottlenecks.push({
|
|
420
|
-
operation,
|
|
421
|
-
severity: 'medium',
|
|
422
|
-
impact: 'High response time variance',
|
|
423
|
-
occurrences: operationMetrics.length,
|
|
424
|
-
averageDelay: 0,
|
|
425
|
-
recommendation: 'Investigate inconsistent performance patterns'
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// Check for high error rate
|
|
430
|
-
const errorCount = operationMetrics.filter(m => !m.success).length;
|
|
431
|
-
const errorRate = errorCount / operationMetrics.length;
|
|
432
|
-
if (errorRate > 0.1) { // > 10% error rate
|
|
433
|
-
bottlenecks.push({
|
|
434
|
-
operation,
|
|
435
|
-
severity: errorRate > 0.5 ? 'critical' : errorRate > 0.25 ? 'high' : 'medium',
|
|
436
|
-
impact: `${(errorRate * 100).toFixed(1)}% error rate`,
|
|
437
|
-
occurrences: errorCount,
|
|
438
|
-
averageDelay: 0,
|
|
439
|
-
recommendation: 'Review error handling and retry logic'
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
return bottlenecks.sort((a, b) =>
|
|
445
|
-
this.severityScore(b.severity) - this.severityScore(a.severity)
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Shutdown the tracker
|
|
451
|
-
*/
|
|
452
|
-
async shutdown(): Promise<void> {
|
|
453
|
-
this.logger.info('Shutting down Performance Tracker...');
|
|
454
|
-
|
|
455
|
-
// Stop timers
|
|
456
|
-
if (this.aggregationTimer) {
|
|
457
|
-
clearInterval(this.aggregationTimer);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Flush remaining metrics
|
|
461
|
-
await this.flushMetrics();
|
|
462
|
-
|
|
463
|
-
this.initialized = false;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Private helper methods
|
|
468
|
-
*/
|
|
469
|
-
private async createPerformanceTables(): Promise<void> {
|
|
470
|
-
await this.memory.execute(`
|
|
471
|
-
CREATE TABLE IF NOT EXISTS performance_metrics (
|
|
472
|
-
id TEXT PRIMARY KEY,
|
|
473
|
-
operation TEXT NOT NULL,
|
|
474
|
-
start_time INTEGER NOT NULL,
|
|
475
|
-
end_time INTEGER,
|
|
476
|
-
duration INTEGER,
|
|
477
|
-
success BOOLEAN NOT NULL,
|
|
478
|
-
session_id TEXT,
|
|
479
|
-
agent_id TEXT,
|
|
480
|
-
metadata TEXT,
|
|
481
|
-
resource_usage TEXT,
|
|
482
|
-
error TEXT,
|
|
483
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
484
|
-
);
|
|
485
|
-
|
|
486
|
-
CREATE INDEX IF NOT EXISTS idx_performance_operation ON performance_metrics(operation);
|
|
487
|
-
CREATE INDEX IF NOT EXISTS idx_performance_session ON performance_metrics(session_id);
|
|
488
|
-
CREATE INDEX IF NOT EXISTS idx_performance_time ON performance_metrics(start_time);
|
|
489
|
-
|
|
490
|
-
CREATE TABLE IF NOT EXISTS performance_aggregates (
|
|
491
|
-
id TEXT PRIMARY KEY,
|
|
492
|
-
operation TEXT NOT NULL,
|
|
493
|
-
period TEXT NOT NULL,
|
|
494
|
-
timestamp INTEGER NOT NULL,
|
|
495
|
-
metrics TEXT NOT NULL,
|
|
496
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
497
|
-
);
|
|
498
|
-
`);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
private startAggregation(): void {
|
|
502
|
-
this.aggregationTimer = setInterval(async () => {
|
|
503
|
-
await this.flushMetrics();
|
|
504
|
-
await this.aggregateMetrics();
|
|
505
|
-
}, this.config.aggregationInterval);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
private startResourceMonitoring(): void {
|
|
509
|
-
// Monitor Node.js process resources
|
|
510
|
-
setInterval(() => {
|
|
511
|
-
const usage = this.captureResourceUsage();
|
|
512
|
-
|
|
513
|
-
// Check thresholds
|
|
514
|
-
if (usage.memoryUsage > 0.8) {
|
|
515
|
-
this.emit('resource:warning', {
|
|
516
|
-
type: 'memory',
|
|
517
|
-
usage: usage.memoryUsage,
|
|
518
|
-
threshold: 0.8
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if (usage.cpuUsage > 0.8) {
|
|
523
|
-
this.emit('resource:warning', {
|
|
524
|
-
type: 'cpu',
|
|
525
|
-
usage: usage.cpuUsage,
|
|
526
|
-
threshold: 0.8
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
}, 10000); // Every 10 seconds
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
private captureResourceUsage(): ResourceUsage {
|
|
533
|
-
const usage = process.cpuUsage();
|
|
534
|
-
const memory = process.memoryUsage();
|
|
535
|
-
|
|
536
|
-
return {
|
|
537
|
-
cpuUsage: (usage.user + usage.system) / 1000000, // Convert to seconds
|
|
538
|
-
memoryUsage: memory.rss / 1024 / 1024, // Convert to MB
|
|
539
|
-
heapUsed: memory.heapUsed / 1024 / 1024,
|
|
540
|
-
heapTotal: memory.heapTotal / 1024 / 1024,
|
|
541
|
-
external: memory.external / 1024 / 1024,
|
|
542
|
-
arrayBuffers: memory.arrayBuffers / 1024 / 1024
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
private calculateResourceDelta(start: ResourceUsage, end: ResourceUsage): ResourceUsage {
|
|
547
|
-
return {
|
|
548
|
-
cpuUsage: end.cpuUsage - start.cpuUsage,
|
|
549
|
-
memoryUsage: end.memoryUsage - start.memoryUsage,
|
|
550
|
-
heapUsed: end.heapUsed - start.heapUsed,
|
|
551
|
-
heapTotal: end.heapTotal,
|
|
552
|
-
external: end.external - start.external,
|
|
553
|
-
arrayBuffers: end.arrayBuffers - start.arrayBuffers
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
private async flushMetrics(): Promise<void> {
|
|
558
|
-
if (this.metricsBuffer.length === 0) return;
|
|
559
|
-
|
|
560
|
-
const metrics = [...this.metricsBuffer];
|
|
561
|
-
this.metricsBuffer = [];
|
|
562
|
-
|
|
563
|
-
// Store metrics in database
|
|
564
|
-
for (const metric of metrics) {
|
|
565
|
-
await this.memory.insert('performance_metrics', {
|
|
566
|
-
id: metric.id,
|
|
567
|
-
operation: metric.operation,
|
|
568
|
-
start_time: metric.startTime,
|
|
569
|
-
end_time: metric.endTime,
|
|
570
|
-
duration: metric.duration,
|
|
571
|
-
success: metric.success,
|
|
572
|
-
session_id: metric.sessionId,
|
|
573
|
-
agent_id: metric.agentId,
|
|
574
|
-
metadata: JSON.stringify(metric.metadata),
|
|
575
|
-
resource_usage: JSON.stringify(metric.resourceUsage),
|
|
576
|
-
error: metric.error
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
this.emit('metrics:flushed', { count: metrics.length });
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
private async aggregateMetrics(): Promise<void> {
|
|
584
|
-
// Aggregate metrics for different time periods
|
|
585
|
-
const operations = await this.memory.query<{ operation: string }>(`
|
|
586
|
-
SELECT DISTINCT operation FROM performance_metrics
|
|
587
|
-
WHERE start_time > ?
|
|
588
|
-
`, [Date.now() - this.config.aggregationInterval]);
|
|
589
|
-
|
|
590
|
-
for (const { operation } of operations) {
|
|
591
|
-
const aggregate = await this.getAggregateMetrics(operation, this.config.aggregationInterval);
|
|
592
|
-
|
|
593
|
-
await this.memory.insert('performance_aggregates', {
|
|
594
|
-
id: `${operation}_${Date.now()}`,
|
|
595
|
-
operation,
|
|
596
|
-
period: 'interval',
|
|
597
|
-
timestamp: Date.now(),
|
|
598
|
-
metrics: JSON.stringify(aggregate)
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// Clean up old metrics
|
|
603
|
-
await this.cleanupOldMetrics();
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
private async cleanupOldMetrics(): Promise<void> {
|
|
607
|
-
const cutoff = Date.now() - this.config.metricsRetention;
|
|
608
|
-
|
|
609
|
-
await this.memory.execute(`
|
|
610
|
-
DELETE FROM performance_metrics WHERE start_time < ?
|
|
611
|
-
`, [cutoff]);
|
|
612
|
-
|
|
613
|
-
await this.memory.execute(`
|
|
614
|
-
DELETE FROM performance_aggregates WHERE timestamp < ?
|
|
615
|
-
`, [cutoff]);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
private checkPerformanceThresholds(metric: PerformanceMetric): void {
|
|
619
|
-
// Check for slow operations
|
|
620
|
-
if (metric.duration && metric.duration > 10000) { // > 10 seconds
|
|
621
|
-
this.emit('performance:slow', {
|
|
622
|
-
operation: metric.operation,
|
|
623
|
-
duration: metric.duration,
|
|
624
|
-
metadata: metric.metadata
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
// Check for failures
|
|
629
|
-
if (!metric.success) {
|
|
630
|
-
this.emit('performance:failure', {
|
|
631
|
-
operation: metric.operation,
|
|
632
|
-
error: metric.error,
|
|
633
|
-
metadata: metric.metadata
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// Check for high resource usage
|
|
638
|
-
if (metric.resourceUsage && metric.resourceUsage.memoryUsage > 100) { // > 100MB
|
|
639
|
-
this.emit('performance:high-memory', {
|
|
640
|
-
operation: metric.operation,
|
|
641
|
-
memoryUsage: metric.resourceUsage.memoryUsage,
|
|
642
|
-
metadata: metric.metadata
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
private generateMetricId(): string {
|
|
648
|
-
return `metric_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
private calculatePercentile(values: number[], percentile: number): number {
|
|
652
|
-
if (values.length === 0) return 0;
|
|
653
|
-
|
|
654
|
-
const index = Math.ceil(values.length * percentile) - 1;
|
|
655
|
-
return values[index] || 0;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
private calculateVariance(values: number[]): number {
|
|
659
|
-
if (values.length === 0) return 0;
|
|
660
|
-
|
|
661
|
-
const mean = values.reduce((a, b) => a + b, 0) / values.length;
|
|
662
|
-
const squaredDiffs = values.map(v => Math.pow(v - mean, 2));
|
|
663
|
-
return squaredDiffs.reduce((a, b) => a + b, 0) / values.length;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
private calculatePeakConcurrency(metrics: PerformanceMetric[]): number {
|
|
667
|
-
if (metrics.length === 0) return 0;
|
|
668
|
-
|
|
669
|
-
const events: Array<{ time: number; type: 'start' | 'end' }> = [];
|
|
670
|
-
|
|
671
|
-
for (const metric of metrics) {
|
|
672
|
-
events.push({ time: metric.startTime, type: 'start' });
|
|
673
|
-
if (metric.endTime) {
|
|
674
|
-
events.push({ time: metric.endTime, type: 'end' });
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
events.sort((a, b) => a.time - b.time);
|
|
679
|
-
|
|
680
|
-
let concurrent = 0;
|
|
681
|
-
let peak = 0;
|
|
682
|
-
|
|
683
|
-
for (const event of events) {
|
|
684
|
-
if (event.type === 'start') {
|
|
685
|
-
concurrent++;
|
|
686
|
-
peak = Math.max(peak, concurrent);
|
|
687
|
-
} else {
|
|
688
|
-
concurrent--;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
return peak;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
private async countSessionArtifacts(sessionId: string): Promise<number> {
|
|
696
|
-
const result = await this.memory.query<{ count: number }>(`
|
|
697
|
-
SELECT COUNT(*) as count FROM servicenow_artifacts
|
|
698
|
-
WHERE session_id = ?
|
|
699
|
-
`, [sessionId]);
|
|
700
|
-
|
|
701
|
-
return result[0]?.count || 0;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
private groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {
|
|
705
|
-
return array.reduce((groups, item) => {
|
|
706
|
-
const group = String(item[key]);
|
|
707
|
-
if (!groups[group]) groups[group] = [];
|
|
708
|
-
groups[group].push(item);
|
|
709
|
-
return groups;
|
|
710
|
-
}, {} as Record<string, T[]>);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
private getTimeframe(period: string): number {
|
|
714
|
-
const timeframes: Record<string, number> = {
|
|
715
|
-
hour: 3600000,
|
|
716
|
-
day: 86400000,
|
|
717
|
-
week: 604800000,
|
|
718
|
-
month: 2592000000
|
|
719
|
-
};
|
|
720
|
-
|
|
721
|
-
return timeframes[period] || timeframes.day;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
private severityScore(severity: string): number {
|
|
725
|
-
const scores: Record<string, number> = {
|
|
726
|
-
low: 1,
|
|
727
|
-
medium: 2,
|
|
728
|
-
high: 3,
|
|
729
|
-
critical: 4
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
return scores[severity] || 0;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
private generateRecommendations(
|
|
736
|
-
operationMetrics: AggregateMetrics[],
|
|
737
|
-
sessionMetrics: SessionMetrics[],
|
|
738
|
-
bottlenecks: Bottleneck[]
|
|
739
|
-
): string[] {
|
|
740
|
-
const recommendations: string[] = [];
|
|
741
|
-
|
|
742
|
-
// Check for slow operations
|
|
743
|
-
const slowOps = operationMetrics.filter(m => m.averageDuration > 5000);
|
|
744
|
-
if (slowOps.length > 0) {
|
|
745
|
-
recommendations.push(
|
|
746
|
-
`Optimize slow operations: ${slowOps.map(op => op.operation).join(', ')}`
|
|
747
|
-
);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// Check for high error rates
|
|
751
|
-
const errorOps = operationMetrics.filter(m => m.errorRate > 0.1);
|
|
752
|
-
if (errorOps.length > 0) {
|
|
753
|
-
recommendations.push(
|
|
754
|
-
`Review error handling for: ${errorOps.map(op => op.operation).join(', ')}`
|
|
755
|
-
);
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// Check for resource usage
|
|
759
|
-
const highMemorySessions = sessionMetrics.filter(s =>
|
|
760
|
-
s.resourceUsage.some(r => r.memoryUsage > 500)
|
|
761
|
-
);
|
|
762
|
-
if (highMemorySessions.length > 0) {
|
|
763
|
-
recommendations.push(
|
|
764
|
-
'Consider implementing memory optimization strategies'
|
|
765
|
-
);
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// Add bottleneck recommendations
|
|
769
|
-
bottlenecks.forEach(b => {
|
|
770
|
-
if (!recommendations.includes(b.recommendation)) {
|
|
771
|
-
recommendations.push(b.recommendation);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
|
|
775
|
-
return recommendations;
|
|
776
|
-
}
|
|
777
|
-
}
|