mcp-wordpress 1.1.7 → 1.2.2
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/README.md +388 -66
- package/dist/cache/CacheInvalidation.d.ts +118 -0
- package/dist/cache/CacheInvalidation.d.ts.map +1 -0
- package/dist/cache/CacheInvalidation.js +349 -0
- package/dist/cache/CacheInvalidation.js.map +1 -0
- package/dist/cache/CacheManager.d.ts +143 -0
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +308 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/cache/HttpCacheWrapper.d.ts +121 -0
- package/dist/cache/HttpCacheWrapper.d.ts.map +1 -0
- package/dist/cache/HttpCacheWrapper.js +280 -0
- package/dist/cache/HttpCacheWrapper.js.map +1 -0
- package/dist/cache/__tests__/CacheInvalidation.test.d.ts +5 -0
- package/dist/cache/__tests__/CacheInvalidation.test.d.ts.map +1 -0
- package/dist/cache/__tests__/CacheInvalidation.test.js +236 -0
- package/dist/cache/__tests__/CacheInvalidation.test.js.map +1 -0
- package/dist/cache/__tests__/CacheManager.test.d.ts +5 -0
- package/dist/cache/__tests__/CacheManager.test.d.ts.map +1 -0
- package/dist/cache/__tests__/CacheManager.test.js +233 -0
- package/dist/cache/__tests__/CacheManager.test.js.map +1 -0
- package/dist/cache/__tests__/CachedWordPressClient.test.d.ts +5 -0
- package/dist/cache/__tests__/CachedWordPressClient.test.d.ts.map +1 -0
- package/dist/cache/__tests__/CachedWordPressClient.test.js +228 -0
- package/dist/cache/__tests__/CachedWordPressClient.test.js.map +1 -0
- package/dist/cache/__tests__/HttpCacheWrapper.test.d.ts +5 -0
- package/dist/cache/__tests__/HttpCacheWrapper.test.d.ts.map +1 -0
- package/dist/cache/__tests__/HttpCacheWrapper.test.js +296 -0
- package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -0
- package/dist/cache/index.d.ts +12 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +9 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/client/CachedWordPressClient.d.ts +160 -0
- package/dist/client/CachedWordPressClient.d.ts.map +1 -0
- package/dist/client/CachedWordPressClient.js +338 -0
- package/dist/client/CachedWordPressClient.js.map +1 -0
- package/dist/client/WordPressClient.d.ts +81 -0
- package/dist/client/WordPressClient.d.ts.map +1 -0
- package/dist/client/WordPressClient.js +354 -0
- package/dist/client/WordPressClient.js.map +1 -0
- package/dist/config/ConfigurationSchema.d.ts +281 -0
- package/dist/config/ConfigurationSchema.d.ts.map +1 -0
- package/dist/config/ConfigurationSchema.js +205 -0
- package/dist/config/ConfigurationSchema.js.map +1 -0
- package/dist/config/ServerConfiguration.d.ts +38 -0
- package/dist/config/ServerConfiguration.d.ts.map +1 -0
- package/dist/config/ServerConfiguration.js +158 -0
- package/dist/config/ServerConfiguration.js.map +1 -0
- package/dist/docs/DocumentationGenerator.d.ts +184 -0
- package/dist/docs/DocumentationGenerator.d.ts.map +1 -0
- package/dist/docs/DocumentationGenerator.js +735 -0
- package/dist/docs/DocumentationGenerator.js.map +1 -0
- package/dist/docs/MarkdownFormatter.d.ts +84 -0
- package/dist/docs/MarkdownFormatter.d.ts.map +1 -0
- package/dist/docs/MarkdownFormatter.js +448 -0
- package/dist/docs/MarkdownFormatter.js.map +1 -0
- package/dist/docs/index.d.ts +8 -0
- package/dist/docs/index.d.ts.map +1 -0
- package/dist/docs/index.js +7 -0
- package/dist/docs/index.js.map +1 -0
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -212
- package/dist/index.js.map +1 -1
- package/dist/performance/AnomalyDetector.d.ts +63 -0
- package/dist/performance/AnomalyDetector.d.ts.map +1 -0
- package/dist/performance/AnomalyDetector.js +222 -0
- package/dist/performance/AnomalyDetector.js.map +1 -0
- package/dist/performance/BenchmarkAnalyzer.d.ts +67 -0
- package/dist/performance/BenchmarkAnalyzer.d.ts.map +1 -0
- package/dist/performance/BenchmarkAnalyzer.js +301 -0
- package/dist/performance/BenchmarkAnalyzer.js.map +1 -0
- package/dist/performance/MetricsCollector.d.ts +139 -0
- package/dist/performance/MetricsCollector.d.ts.map +1 -0
- package/dist/performance/MetricsCollector.js +320 -0
- package/dist/performance/MetricsCollector.js.map +1 -0
- package/dist/performance/PerformanceAnalytics.d.ts +162 -0
- package/dist/performance/PerformanceAnalytics.d.ts.map +1 -0
- package/dist/performance/PerformanceAnalytics.js +554 -0
- package/dist/performance/PerformanceAnalytics.js.map +1 -0
- package/dist/performance/PerformanceMonitor.d.ts +202 -0
- package/dist/performance/PerformanceMonitor.d.ts.map +1 -0
- package/dist/performance/PerformanceMonitor.js +478 -0
- package/dist/performance/PerformanceMonitor.js.map +1 -0
- package/dist/performance/TrendAnalyzer.d.ts +69 -0
- package/dist/performance/TrendAnalyzer.d.ts.map +1 -0
- package/dist/performance/TrendAnalyzer.js +203 -0
- package/dist/performance/TrendAnalyzer.js.map +1 -0
- package/dist/performance/index.d.ts +11 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +8 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/security/InputValidator.d.ts +215 -0
- package/dist/security/InputValidator.d.ts.map +1 -0
- package/dist/security/InputValidator.js +278 -0
- package/dist/security/InputValidator.js.map +1 -0
- package/dist/security/SecurityConfig.d.ts +129 -0
- package/dist/security/SecurityConfig.d.ts.map +1 -0
- package/dist/security/SecurityConfig.js +262 -0
- package/dist/security/SecurityConfig.js.map +1 -0
- package/dist/server/ConnectionTester.d.ts +24 -0
- package/dist/server/ConnectionTester.d.ts.map +1 -0
- package/dist/server/ConnectionTester.js +61 -0
- package/dist/server/ConnectionTester.js.map +1 -0
- package/dist/server/ToolRegistry.d.ts +46 -0
- package/dist/server/ToolRegistry.d.ts.map +1 -0
- package/dist/server/ToolRegistry.js +148 -0
- package/dist/server/ToolRegistry.js.map +1 -0
- package/dist/tools/BaseToolClass.d.ts +76 -0
- package/dist/tools/BaseToolClass.d.ts.map +1 -0
- package/dist/tools/BaseToolClass.js +104 -0
- package/dist/tools/BaseToolClass.js.map +1 -0
- package/dist/tools/BaseToolManager.d.ts +26 -0
- package/dist/tools/BaseToolManager.d.ts.map +1 -0
- package/dist/tools/BaseToolManager.js +56 -0
- package/dist/tools/BaseToolManager.js.map +1 -0
- package/dist/tools/base.d.ts +37 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +60 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/cache.d.ts +260 -0
- package/dist/tools/cache.d.ts.map +1 -0
- package/dist/tools/cache.js +237 -0
- package/dist/tools/cache.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/performance.d.ts +63 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js +865 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/types/client.d.ts +1 -0
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js.map +1 -1
- package/dist/utils/toolWrapper.d.ts +4 -0
- package/dist/utils/toolWrapper.d.ts.map +1 -1
- package/dist/utils/toolWrapper.js +11 -0
- package/dist/utils/toolWrapper.js.map +1 -1
- package/dist/utils/validation.d.ts +68 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +185 -0
- package/dist/utils/validation.js.map +1 -0
- package/docs/CACHING.md +340 -0
- package/docs/DOCKER.md +451 -0
- package/docs/PERFORMANCE_MONITORING.md +471 -0
- package/docs/SECURITY_TESTING.md +393 -0
- package/docs/api/README.md +200 -0
- package/docs/api/categories/auth.md +40 -0
- package/docs/api/categories/cache.md +41 -0
- package/docs/api/categories/comment.md +44 -0
- package/docs/api/categories/media.md +43 -0
- package/docs/api/categories/page.md +43 -0
- package/docs/api/categories/performance.md +44 -0
- package/docs/api/categories/post.md +43 -0
- package/docs/api/categories/site.md +43 -0
- package/docs/api/categories/taxonomy.md +47 -0
- package/docs/api/categories/user.md +43 -0
- package/docs/api/openapi.json +3305 -0
- package/docs/api/summary.json +12 -0
- package/docs/api/tools/wp_approve_comment.md +98 -0
- package/docs/api/tools/wp_cache_clear.md +120 -0
- package/docs/api/tools/wp_cache_info.md +119 -0
- package/docs/api/tools/wp_cache_stats.md +119 -0
- package/docs/api/tools/wp_cache_warm.md +119 -0
- package/docs/api/tools/wp_create_application_password.md +102 -0
- package/docs/api/tools/wp_create_category.md +102 -0
- package/docs/api/tools/wp_create_comment.md +128 -0
- package/docs/api/tools/wp_create_page.md +135 -0
- package/docs/api/tools/wp_create_post.md +147 -0
- package/docs/api/tools/wp_create_tag.md +101 -0
- package/docs/api/tools/wp_create_user.md +135 -0
- package/docs/api/tools/wp_delete_application_password.md +101 -0
- package/docs/api/tools/wp_delete_category.md +100 -0
- package/docs/api/tools/wp_delete_comment.md +101 -0
- package/docs/api/tools/wp_delete_media.md +108 -0
- package/docs/api/tools/wp_delete_page.md +108 -0
- package/docs/api/tools/wp_delete_post.md +117 -0
- package/docs/api/tools/wp_delete_tag.md +100 -0
- package/docs/api/tools/wp_delete_user.md +108 -0
- package/docs/api/tools/wp_get_application_passwords.md +103 -0
- package/docs/api/tools/wp_get_auth_status.md +101 -0
- package/docs/api/tools/wp_get_category.md +103 -0
- package/docs/api/tools/wp_get_comment.md +103 -0
- package/docs/api/tools/wp_get_current_user.md +101 -0
- package/docs/api/tools/wp_get_media.md +103 -0
- package/docs/api/tools/wp_get_page.md +103 -0
- package/docs/api/tools/wp_get_page_revisions.md +103 -0
- package/docs/api/tools/wp_get_post.md +112 -0
- package/docs/api/tools/wp_get_post_revisions.md +103 -0
- package/docs/api/tools/wp_get_site_settings.md +108 -0
- package/docs/api/tools/wp_get_tag.md +103 -0
- package/docs/api/tools/wp_get_user.md +103 -0
- package/docs/api/tools/wp_list_categories.md +111 -0
- package/docs/api/tools/wp_list_comments.md +111 -0
- package/docs/api/tools/wp_list_media.md +145 -0
- package/docs/api/tools/wp_list_pages.md +145 -0
- package/docs/api/tools/wp_list_posts.md +156 -0
- package/docs/api/tools/wp_list_tags.md +110 -0
- package/docs/api/tools/wp_list_users.md +111 -0
- package/docs/api/tools/wp_performance_alerts.md +162 -0
- package/docs/api/tools/wp_performance_benchmark.md +160 -0
- package/docs/api/tools/wp_performance_export.md +162 -0
- package/docs/api/tools/wp_performance_history.md +161 -0
- package/docs/api/tools/wp_performance_optimize.md +162 -0
- package/docs/api/tools/wp_performance_stats.md +160 -0
- package/docs/api/tools/wp_search_site.md +99 -0
- package/docs/api/tools/wp_spam_comment.md +98 -0
- package/docs/api/tools/wp_switch_auth_method.md +122 -0
- package/docs/api/tools/wp_test_auth.md +96 -0
- package/docs/api/tools/wp_update_category.md +102 -0
- package/docs/api/tools/wp_update_comment.md +127 -0
- package/docs/api/tools/wp_update_media.md +129 -0
- package/docs/api/tools/wp_update_page.md +135 -0
- package/docs/api/tools/wp_update_post.md +144 -0
- package/docs/api/tools/wp_update_site_settings.md +127 -0
- package/docs/api/tools/wp_update_tag.md +102 -0
- package/docs/api/tools/wp_update_user.md +134 -0
- package/docs/api/tools/wp_upload_media.md +131 -0
- package/docs/api/types/WordPressPost.md +39 -0
- package/docs/contract-testing.md +183 -0
- package/docs/developer/NPM_AUTH_SETUP.md +3 -3
- package/docs/wordpress-rest-api-authentication-troubleshooting.md +218 -0
- package/package.json +84 -64
- package/src/cache/CacheInvalidation.ts +421 -0
- package/src/cache/CacheManager.ts +391 -0
- package/src/cache/HttpCacheWrapper.ts +372 -0
- package/src/cache/__tests__/CacheInvalidation.test.ts +299 -0
- package/src/cache/__tests__/CacheManager.test.ts +300 -0
- package/src/cache/__tests__/CachedWordPressClient.test.ts +304 -0
- package/src/cache/__tests__/HttpCacheWrapper.test.ts +359 -0
- package/src/cache/index.ts +26 -0
- package/src/client/CachedWordPressClient.ts +442 -0
- package/src/config/ConfigurationSchema.ts +246 -0
- package/src/config/ServerConfiguration.ts +215 -0
- package/src/docs/DocumentationGenerator.ts +952 -0
- package/src/docs/MarkdownFormatter.ts +494 -0
- package/src/docs/index.ts +21 -0
- package/src/index.ts +14 -274
- package/src/performance/MetricsCollector.ts +447 -0
- package/src/performance/PerformanceAnalytics.ts +762 -0
- package/src/performance/PerformanceMonitor.ts +649 -0
- package/src/performance/index.ts +28 -0
- package/src/security/InputValidator.ts +319 -0
- package/src/security/SecurityConfig.ts +301 -0
- package/src/server/ConnectionTester.ts +74 -0
- package/src/server/ToolRegistry.ts +194 -0
- package/src/tools/BaseToolManager.ts +66 -0
- package/src/tools/cache.ts +259 -0
- package/src/tools/index.ts +2 -0
- package/src/tools/performance.ts +948 -0
- package/src/types/client.ts +1 -0
- package/src/utils/toolWrapper.ts +11 -0
- package/src/utils/validation.ts +259 -0
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Performance Analytics for WordPress MCP Server
|
|
3
|
+
* Provides insights, predictions, and optimization recommendations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { PerformanceMetrics } from './PerformanceMonitor.js';
|
|
7
|
+
import { MetricsCollector } from './MetricsCollector.js';
|
|
8
|
+
|
|
9
|
+
export interface AnalyticsConfig {
|
|
10
|
+
enablePredictiveAnalysis: boolean;
|
|
11
|
+
enableAnomalyDetection: boolean;
|
|
12
|
+
enableTrendAnalysis: boolean;
|
|
13
|
+
lookbackPeriod: number; // in milliseconds
|
|
14
|
+
sensitivityLevel: 'low' | 'medium' | 'high';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PerformanceTrend {
|
|
18
|
+
metric: string;
|
|
19
|
+
direction: 'improving' | 'declining' | 'stable';
|
|
20
|
+
changeRate: number; // percentage change
|
|
21
|
+
confidence: number; // 0-1
|
|
22
|
+
prediction: {
|
|
23
|
+
nextValue: number;
|
|
24
|
+
timeframe: number; // milliseconds
|
|
25
|
+
confidence: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface PerformanceAnomaly {
|
|
30
|
+
timestamp: number;
|
|
31
|
+
metric: string;
|
|
32
|
+
expectedValue: number;
|
|
33
|
+
actualValue: number;
|
|
34
|
+
deviation: number; // percentage
|
|
35
|
+
severity: 'minor' | 'moderate' | 'major' | 'critical';
|
|
36
|
+
possibleCauses: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PerformanceInsight {
|
|
40
|
+
id: string;
|
|
41
|
+
category: 'optimization' | 'scaling' | 'maintenance' | 'alert';
|
|
42
|
+
priority: 'low' | 'medium' | 'high' | 'critical';
|
|
43
|
+
title: string;
|
|
44
|
+
description: string;
|
|
45
|
+
impact: 'performance' | 'reliability' | 'cost' | 'user_experience';
|
|
46
|
+
recommendation: string;
|
|
47
|
+
estimatedImprovement: string;
|
|
48
|
+
implementationEffort: 'low' | 'medium' | 'high';
|
|
49
|
+
relatedMetrics: string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface BenchmarkComparison {
|
|
53
|
+
category: string;
|
|
54
|
+
currentValue: number;
|
|
55
|
+
benchmarkValue: number;
|
|
56
|
+
percentile: number; // Where current performance ranks (0-100)
|
|
57
|
+
status: 'excellent' | 'good' | 'average' | 'below_average' | 'poor';
|
|
58
|
+
improvement: number; // How much improvement needed to reach next tier
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Performance Analytics Engine
|
|
63
|
+
*/
|
|
64
|
+
export class PerformanceAnalytics {
|
|
65
|
+
private collector: MetricsCollector;
|
|
66
|
+
private config: AnalyticsConfig;
|
|
67
|
+
private historicalData: PerformanceMetrics[] = [];
|
|
68
|
+
private detectedAnomalies: PerformanceAnomaly[] = [];
|
|
69
|
+
private generatedInsights: PerformanceInsight[] = [];
|
|
70
|
+
|
|
71
|
+
// Performance benchmarks (based on industry standards)
|
|
72
|
+
private benchmarks = {
|
|
73
|
+
responseTime: {
|
|
74
|
+
excellent: 200, // <200ms
|
|
75
|
+
good: 500, // 200-500ms
|
|
76
|
+
average: 1000, // 500ms-1s
|
|
77
|
+
below_average: 2000, // 1-2s
|
|
78
|
+
poor: Infinity // >2s
|
|
79
|
+
},
|
|
80
|
+
cacheHitRate: {
|
|
81
|
+
excellent: 0.95, // >95%
|
|
82
|
+
good: 0.85, // 85-95%
|
|
83
|
+
average: 0.70, // 70-85%
|
|
84
|
+
below_average: 0.50, // 50-70%
|
|
85
|
+
poor: 0 // <50%
|
|
86
|
+
},
|
|
87
|
+
errorRate: {
|
|
88
|
+
excellent: 0.001, // <0.1%
|
|
89
|
+
good: 0.01, // 0.1-1%
|
|
90
|
+
average: 0.02, // 1-2%
|
|
91
|
+
below_average: 0.05, // 2-5%
|
|
92
|
+
poor: Infinity // >5%
|
|
93
|
+
},
|
|
94
|
+
memoryUsage: {
|
|
95
|
+
excellent: 50, // <50%
|
|
96
|
+
good: 70, // 50-70%
|
|
97
|
+
average: 80, // 70-80%
|
|
98
|
+
below_average: 90, // 80-90%
|
|
99
|
+
poor: 100 // >90%
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
constructor(collector: MetricsCollector, config: Partial<AnalyticsConfig> = {}) {
|
|
104
|
+
this.collector = collector;
|
|
105
|
+
this.config = {
|
|
106
|
+
enablePredictiveAnalysis: true,
|
|
107
|
+
enableAnomalyDetection: true,
|
|
108
|
+
enableTrendAnalysis: true,
|
|
109
|
+
lookbackPeriod: 24 * 60 * 60 * 1000, // 24 hours
|
|
110
|
+
sensitivityLevel: 'medium',
|
|
111
|
+
...config
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Add historical data point for analysis
|
|
117
|
+
*/
|
|
118
|
+
addDataPoint(metrics: PerformanceMetrics): void {
|
|
119
|
+
this.historicalData.push(metrics);
|
|
120
|
+
|
|
121
|
+
// Limit historical data to lookback period
|
|
122
|
+
const cutoff = Date.now() - this.config.lookbackPeriod;
|
|
123
|
+
this.historicalData = this.historicalData.filter(
|
|
124
|
+
data => data.system.uptime > cutoff
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// Run analysis on new data
|
|
128
|
+
if (this.config.enableAnomalyDetection) {
|
|
129
|
+
this.detectAnomalies(metrics);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Analyze performance trends
|
|
135
|
+
*/
|
|
136
|
+
analyzeTrends(): PerformanceTrend[] {
|
|
137
|
+
if (!this.config.enableTrendAnalysis || this.historicalData.length < 5) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const trends: PerformanceTrend[] = [];
|
|
142
|
+
|
|
143
|
+
// Analyze response time trend
|
|
144
|
+
trends.push(this.analyzeTrend(
|
|
145
|
+
'responseTime',
|
|
146
|
+
this.historicalData.map(d => d.requests.averageResponseTime)
|
|
147
|
+
));
|
|
148
|
+
|
|
149
|
+
// Analyze cache hit rate trend
|
|
150
|
+
trends.push(this.analyzeTrend(
|
|
151
|
+
'cacheHitRate',
|
|
152
|
+
this.historicalData.map(d => d.cache.hitRate)
|
|
153
|
+
));
|
|
154
|
+
|
|
155
|
+
// Analyze error rate trend
|
|
156
|
+
trends.push(this.analyzeTrend(
|
|
157
|
+
'errorRate',
|
|
158
|
+
this.historicalData.map(d =>
|
|
159
|
+
d.requests.total > 0 ? d.requests.failed / d.requests.total : 0
|
|
160
|
+
)
|
|
161
|
+
));
|
|
162
|
+
|
|
163
|
+
// Analyze memory usage trend
|
|
164
|
+
trends.push(this.analyzeTrend(
|
|
165
|
+
'memoryUsage',
|
|
166
|
+
this.historicalData.map(d => d.system.memoryUsage)
|
|
167
|
+
));
|
|
168
|
+
|
|
169
|
+
// Analyze request volume trend
|
|
170
|
+
trends.push(this.analyzeTrend(
|
|
171
|
+
'requestVolume',
|
|
172
|
+
this.historicalData.map(d => d.requests.requestsPerSecond)
|
|
173
|
+
));
|
|
174
|
+
|
|
175
|
+
return trends;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Generate performance insights
|
|
180
|
+
*/
|
|
181
|
+
generateInsights(): PerformanceInsight[] {
|
|
182
|
+
const insights: PerformanceInsight[] = [];
|
|
183
|
+
const currentMetrics = this.collector.collectCurrentMetrics();
|
|
184
|
+
const trends = this.analyzeTrends();
|
|
185
|
+
|
|
186
|
+
// Cache optimization insights
|
|
187
|
+
if (currentMetrics.cache.hitRate < 0.8) {
|
|
188
|
+
insights.push({
|
|
189
|
+
id: 'cache-optimization-1',
|
|
190
|
+
category: 'optimization',
|
|
191
|
+
priority: 'high',
|
|
192
|
+
title: 'Improve Cache Hit Rate',
|
|
193
|
+
description: `Current cache hit rate is ${(currentMetrics.cache.hitRate * 100).toFixed(1)}%, which is below optimal performance.`,
|
|
194
|
+
impact: 'performance',
|
|
195
|
+
recommendation: 'Implement cache warming strategies and optimize TTL values for frequently accessed data.',
|
|
196
|
+
estimatedImprovement: '20-40% reduction in response times',
|
|
197
|
+
implementationEffort: 'medium',
|
|
198
|
+
relatedMetrics: ['cacheHitRate', 'responseTime']
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Response time insights
|
|
203
|
+
if (currentMetrics.requests.averageResponseTime > 1000) {
|
|
204
|
+
insights.push({
|
|
205
|
+
id: 'response-time-1',
|
|
206
|
+
category: 'optimization',
|
|
207
|
+
priority: 'high',
|
|
208
|
+
title: 'Reduce Response Times',
|
|
209
|
+
description: `Average response time of ${currentMetrics.requests.averageResponseTime.toFixed(0)}ms is above recommended threshold.`,
|
|
210
|
+
impact: 'user_experience',
|
|
211
|
+
recommendation: 'Enable aggressive caching, optimize database queries, or consider upgrading server resources.',
|
|
212
|
+
estimatedImprovement: '50-70% reduction in response times',
|
|
213
|
+
implementationEffort: 'medium',
|
|
214
|
+
relatedMetrics: ['responseTime', 'cacheHitRate']
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Memory usage insights
|
|
219
|
+
if (currentMetrics.system.memoryUsage > 80) {
|
|
220
|
+
insights.push({
|
|
221
|
+
id: 'memory-usage-1',
|
|
222
|
+
category: 'scaling',
|
|
223
|
+
priority: 'medium',
|
|
224
|
+
title: 'Memory Usage Optimization',
|
|
225
|
+
description: `Memory usage at ${currentMetrics.system.memoryUsage}% is approaching limits.`,
|
|
226
|
+
impact: 'reliability',
|
|
227
|
+
recommendation: 'Increase cache size limits, implement cache eviction policies, or scale server resources.',
|
|
228
|
+
estimatedImprovement: 'Improved system stability',
|
|
229
|
+
implementationEffort: 'low',
|
|
230
|
+
relatedMetrics: ['memoryUsage', 'cacheSize']
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Tool usage insights
|
|
235
|
+
const toolMetrics = currentMetrics.tools;
|
|
236
|
+
if (Object.keys(toolMetrics.toolUsageCount).length > 0) {
|
|
237
|
+
const mostUsed = Object.entries(toolMetrics.toolUsageCount)
|
|
238
|
+
.sort(([,a], [,b]) => b - a)
|
|
239
|
+
.slice(0, 3);
|
|
240
|
+
|
|
241
|
+
insights.push({
|
|
242
|
+
id: 'tool-usage-1',
|
|
243
|
+
category: 'optimization',
|
|
244
|
+
priority: 'low',
|
|
245
|
+
title: 'Optimize Frequently Used Tools',
|
|
246
|
+
description: `Most used tools: ${mostUsed.map(([tool]) => tool).join(', ')}. Consider optimizing these workflows.`,
|
|
247
|
+
impact: 'performance',
|
|
248
|
+
recommendation: 'Create cached workflows or batch operations for frequently used tools.',
|
|
249
|
+
estimatedImprovement: '10-20% reduction in API calls',
|
|
250
|
+
implementationEffort: 'high',
|
|
251
|
+
relatedMetrics: ['toolUsage', 'requestVolume']
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Trend-based insights
|
|
256
|
+
const responseTimeTrend = trends.find(t => t.metric === 'responseTime');
|
|
257
|
+
if (responseTimeTrend && responseTimeTrend.direction === 'declining' && responseTimeTrend.changeRate > 10) {
|
|
258
|
+
insights.push({
|
|
259
|
+
id: 'trend-response-time-1',
|
|
260
|
+
category: 'alert',
|
|
261
|
+
priority: 'high',
|
|
262
|
+
title: 'Response Time Degradation Detected',
|
|
263
|
+
description: `Response times are declining at ${responseTimeTrend.changeRate.toFixed(1)}% rate.`,
|
|
264
|
+
impact: 'performance',
|
|
265
|
+
recommendation: 'Investigate recent changes, check WordPress site health, and monitor resource usage.',
|
|
266
|
+
estimatedImprovement: 'Prevent further degradation',
|
|
267
|
+
implementationEffort: 'medium',
|
|
268
|
+
relatedMetrics: ['responseTime', 'errorRate']
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
this.generatedInsights = insights;
|
|
273
|
+
return insights;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Compare performance against benchmarks
|
|
278
|
+
*/
|
|
279
|
+
benchmarkPerformance(): BenchmarkComparison[] {
|
|
280
|
+
const currentMetrics = this.collector.collectCurrentMetrics();
|
|
281
|
+
const comparisons: BenchmarkComparison[] = [];
|
|
282
|
+
|
|
283
|
+
// Response time benchmark
|
|
284
|
+
comparisons.push(this.createBenchmarkComparison(
|
|
285
|
+
'Response Time',
|
|
286
|
+
currentMetrics.requests.averageResponseTime,
|
|
287
|
+
this.benchmarks.responseTime,
|
|
288
|
+
false // lower is better
|
|
289
|
+
));
|
|
290
|
+
|
|
291
|
+
// Cache hit rate benchmark
|
|
292
|
+
comparisons.push(this.createBenchmarkComparison(
|
|
293
|
+
'Cache Hit Rate',
|
|
294
|
+
currentMetrics.cache.hitRate * 100,
|
|
295
|
+
Object.fromEntries(
|
|
296
|
+
Object.entries(this.benchmarks.cacheHitRate).map(([k, v]) => [k, v * 100])
|
|
297
|
+
),
|
|
298
|
+
true // higher is better
|
|
299
|
+
));
|
|
300
|
+
|
|
301
|
+
// Error rate benchmark
|
|
302
|
+
const errorRate = currentMetrics.requests.total > 0
|
|
303
|
+
? (currentMetrics.requests.failed / currentMetrics.requests.total) * 100
|
|
304
|
+
: 0;
|
|
305
|
+
comparisons.push(this.createBenchmarkComparison(
|
|
306
|
+
'Error Rate',
|
|
307
|
+
errorRate,
|
|
308
|
+
Object.fromEntries(
|
|
309
|
+
Object.entries(this.benchmarks.errorRate).map(([k, v]) => [k, v * 100])
|
|
310
|
+
),
|
|
311
|
+
false // lower is better
|
|
312
|
+
));
|
|
313
|
+
|
|
314
|
+
// Memory usage benchmark
|
|
315
|
+
comparisons.push(this.createBenchmarkComparison(
|
|
316
|
+
'Memory Usage',
|
|
317
|
+
currentMetrics.system.memoryUsage,
|
|
318
|
+
this.benchmarks.memoryUsage,
|
|
319
|
+
false // lower is better
|
|
320
|
+
));
|
|
321
|
+
|
|
322
|
+
return comparisons;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Predict future performance based on trends
|
|
327
|
+
*/
|
|
328
|
+
predictPerformance(timeframeMinutes: number = 60): {
|
|
329
|
+
predictions: Array<{
|
|
330
|
+
metric: string;
|
|
331
|
+
currentValue: number;
|
|
332
|
+
predictedValue: number;
|
|
333
|
+
confidence: number;
|
|
334
|
+
trend: 'improving' | 'declining' | 'stable';
|
|
335
|
+
}>;
|
|
336
|
+
alerts: string[];
|
|
337
|
+
} {
|
|
338
|
+
if (!this.config.enablePredictiveAnalysis) {
|
|
339
|
+
return { predictions: [], alerts: [] };
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const trends = this.analyzeTrends();
|
|
343
|
+
const predictions: any[] = [];
|
|
344
|
+
const alerts: string[] = [];
|
|
345
|
+
|
|
346
|
+
for (const trend of trends) {
|
|
347
|
+
const _timeframeMs = timeframeMinutes * 60 * 1000;
|
|
348
|
+
const predictedValue = trend.prediction.nextValue;
|
|
349
|
+
|
|
350
|
+
predictions.push({
|
|
351
|
+
metric: trend.metric,
|
|
352
|
+
currentValue: this.getCurrentMetricValue(trend.metric),
|
|
353
|
+
predictedValue,
|
|
354
|
+
confidence: trend.confidence,
|
|
355
|
+
trend: trend.direction
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
// Generate alerts for concerning predictions
|
|
359
|
+
if (trend.metric === 'responseTime' && predictedValue > 2000 && trend.direction === 'declining') {
|
|
360
|
+
alerts.push(`Response times predicted to exceed 2s in ${timeframeMinutes} minutes`);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (trend.metric === 'cacheHitRate' && predictedValue < 0.5 && trend.direction === 'declining') {
|
|
364
|
+
alerts.push(`Cache hit rate predicted to drop below 50% in ${timeframeMinutes} minutes`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (trend.metric === 'memoryUsage' && predictedValue > 90 && trend.direction === 'declining') {
|
|
368
|
+
alerts.push(`Memory usage predicted to exceed 90% in ${timeframeMinutes} minutes`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return { predictions, alerts };
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Generate optimization recommendations with ROI estimates
|
|
377
|
+
*/
|
|
378
|
+
generateOptimizationPlan(): {
|
|
379
|
+
quickWins: PerformanceInsight[];
|
|
380
|
+
mediumTerm: PerformanceInsight[];
|
|
381
|
+
longTerm: PerformanceInsight[];
|
|
382
|
+
estimatedROI: {
|
|
383
|
+
performanceGain: number; // percentage
|
|
384
|
+
implementationCost: 'low' | 'medium' | 'high';
|
|
385
|
+
timeToValue: number; // days
|
|
386
|
+
};
|
|
387
|
+
} {
|
|
388
|
+
const insights = this.generateInsights();
|
|
389
|
+
|
|
390
|
+
const quickWins = insights.filter(
|
|
391
|
+
i => i.implementationEffort === 'low' && ['high', 'critical'].includes(i.priority)
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
const mediumTerm = insights.filter(
|
|
395
|
+
i => i.implementationEffort === 'medium'
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
const longTerm = insights.filter(
|
|
399
|
+
i => i.implementationEffort === 'high'
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
// Estimate ROI based on current performance issues
|
|
403
|
+
const currentMetrics = this.collector.collectCurrentMetrics();
|
|
404
|
+
let estimatedGain = 0;
|
|
405
|
+
|
|
406
|
+
if (currentMetrics.cache.hitRate < 0.8) estimatedGain += 30;
|
|
407
|
+
if (currentMetrics.requests.averageResponseTime > 1000) estimatedGain += 40;
|
|
408
|
+
if (currentMetrics.system.memoryUsage > 80) estimatedGain += 20;
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
quickWins,
|
|
412
|
+
mediumTerm,
|
|
413
|
+
longTerm,
|
|
414
|
+
estimatedROI: {
|
|
415
|
+
performanceGain: Math.min(estimatedGain, 80), // Cap at 80%
|
|
416
|
+
implementationCost: quickWins.length > 2 ? 'low' : mediumTerm.length > 2 ? 'medium' : 'high',
|
|
417
|
+
timeToValue: quickWins.length > 0 ? 1 : mediumTerm.length > 0 ? 7 : 30
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Get anomalies detected in recent data
|
|
424
|
+
*/
|
|
425
|
+
getAnomalies(severity?: string): PerformanceAnomaly[] {
|
|
426
|
+
if (severity) {
|
|
427
|
+
return this.detectedAnomalies.filter(a => a.severity === severity);
|
|
428
|
+
}
|
|
429
|
+
return [...this.detectedAnomalies];
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Export comprehensive analytics report
|
|
434
|
+
*/
|
|
435
|
+
exportAnalyticsReport(): {
|
|
436
|
+
timestamp: string;
|
|
437
|
+
summary: {
|
|
438
|
+
overallHealth: string;
|
|
439
|
+
keyInsights: number;
|
|
440
|
+
criticalAlerts: number;
|
|
441
|
+
performanceScore: number;
|
|
442
|
+
};
|
|
443
|
+
trends: PerformanceTrend[];
|
|
444
|
+
benchmarks: BenchmarkComparison[];
|
|
445
|
+
insights: PerformanceInsight[];
|
|
446
|
+
anomalies: PerformanceAnomaly[];
|
|
447
|
+
predictions: any;
|
|
448
|
+
optimizationPlan: any;
|
|
449
|
+
} {
|
|
450
|
+
const currentMetrics = this.collector.collectCurrentMetrics();
|
|
451
|
+
const performanceScore = this.calculatePerformanceScore(currentMetrics);
|
|
452
|
+
|
|
453
|
+
return {
|
|
454
|
+
timestamp: new Date().toISOString(),
|
|
455
|
+
summary: {
|
|
456
|
+
overallHealth: this.calculateOverallHealth(performanceScore),
|
|
457
|
+
keyInsights: this.generatedInsights.length,
|
|
458
|
+
criticalAlerts: this.generatedInsights.filter(i => i.priority === 'critical').length,
|
|
459
|
+
performanceScore
|
|
460
|
+
},
|
|
461
|
+
trends: this.analyzeTrends(),
|
|
462
|
+
benchmarks: this.benchmarkPerformance(),
|
|
463
|
+
insights: this.generateInsights(),
|
|
464
|
+
anomalies: this.getAnomalies(),
|
|
465
|
+
predictions: this.predictPerformance(),
|
|
466
|
+
optimizationPlan: this.generateOptimizationPlan()
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Analyze trend for a specific metric
|
|
472
|
+
*/
|
|
473
|
+
private analyzeTrend(metricName: string, values: number[]): PerformanceTrend {
|
|
474
|
+
if (values.length < 3) {
|
|
475
|
+
return {
|
|
476
|
+
metric: metricName,
|
|
477
|
+
direction: 'stable',
|
|
478
|
+
changeRate: 0,
|
|
479
|
+
confidence: 0,
|
|
480
|
+
prediction: { nextValue: values[values.length - 1] || 0, timeframe: 0, confidence: 0 }
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Calculate linear regression
|
|
485
|
+
const n = values.length;
|
|
486
|
+
const x = Array.from({ length: n }, (_, i) => i);
|
|
487
|
+
const y = values;
|
|
488
|
+
|
|
489
|
+
const sumX = x.reduce((a, b) => a + b, 0);
|
|
490
|
+
const sumY = y.reduce((a, b) => a + b, 0);
|
|
491
|
+
const sumXY = x.map((xi, i) => xi * y[i]).reduce((a, b) => a + b, 0);
|
|
492
|
+
const sumXX = x.map(xi => xi * xi).reduce((a, b) => a + b, 0);
|
|
493
|
+
|
|
494
|
+
const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
|
|
495
|
+
const intercept = (sumY - slope * sumX) / n;
|
|
496
|
+
|
|
497
|
+
// Calculate R-squared for confidence
|
|
498
|
+
const yMean = sumY / n;
|
|
499
|
+
const totalSumSquares = y.map(yi => Math.pow(yi - yMean, 2)).reduce((a, b) => a + b, 0);
|
|
500
|
+
const residualSumSquares = y.map((yi, i) => {
|
|
501
|
+
const predicted = slope * x[i] + intercept;
|
|
502
|
+
return Math.pow(yi - predicted, 2);
|
|
503
|
+
}).reduce((a, b) => a + b, 0);
|
|
504
|
+
|
|
505
|
+
const rSquared = 1 - (residualSumSquares / totalSumSquares);
|
|
506
|
+
|
|
507
|
+
// Determine direction and change rate
|
|
508
|
+
const currentValue = values[values.length - 1];
|
|
509
|
+
const previousValue = values[values.length - 2];
|
|
510
|
+
const changeRate = Math.abs((currentValue - previousValue) / previousValue) * 100;
|
|
511
|
+
|
|
512
|
+
let direction: 'improving' | 'declining' | 'stable' = 'stable';
|
|
513
|
+
if (Math.abs(slope) > 0.1) {
|
|
514
|
+
// For metrics where lower is better (response time, error rate)
|
|
515
|
+
if (['responseTime', 'errorRate', 'memoryUsage'].includes(metricName)) {
|
|
516
|
+
direction = slope < 0 ? 'improving' : 'declining';
|
|
517
|
+
} else {
|
|
518
|
+
// For metrics where higher is better (cache hit rate)
|
|
519
|
+
direction = slope > 0 ? 'improving' : 'declining';
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Predict next value
|
|
524
|
+
const nextValue = slope * n + intercept;
|
|
525
|
+
|
|
526
|
+
return {
|
|
527
|
+
metric: metricName,
|
|
528
|
+
direction,
|
|
529
|
+
changeRate,
|
|
530
|
+
confidence: Math.max(0, Math.min(1, rSquared)),
|
|
531
|
+
prediction: {
|
|
532
|
+
nextValue: Math.max(0, nextValue),
|
|
533
|
+
timeframe: 30 * 60 * 1000, // 30 minutes
|
|
534
|
+
confidence: Math.max(0, Math.min(1, rSquared * 0.8)) // Slightly lower confidence for predictions
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Detect anomalies in current metrics
|
|
541
|
+
*/
|
|
542
|
+
private detectAnomalies(metrics: PerformanceMetrics): void {
|
|
543
|
+
if (this.historicalData.length < 10) return; // Need historical context
|
|
544
|
+
|
|
545
|
+
const recentData = this.historicalData.slice(-10);
|
|
546
|
+
|
|
547
|
+
// Check response time anomalies
|
|
548
|
+
const responseTimes = recentData.map(d => d.requests.averageResponseTime);
|
|
549
|
+
this.checkMetricAnomaly(
|
|
550
|
+
'responseTime',
|
|
551
|
+
metrics.requests.averageResponseTime,
|
|
552
|
+
responseTimes,
|
|
553
|
+
'Response time spike detected'
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
// Check cache hit rate anomalies
|
|
557
|
+
const hitRates = recentData.map(d => d.cache.hitRate);
|
|
558
|
+
this.checkMetricAnomaly(
|
|
559
|
+
'cacheHitRate',
|
|
560
|
+
metrics.cache.hitRate,
|
|
561
|
+
hitRates,
|
|
562
|
+
'Cache hit rate drop detected'
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
// Check error rate anomalies
|
|
566
|
+
const errorRates = recentData.map(d =>
|
|
567
|
+
d.requests.total > 0 ? d.requests.failed / d.requests.total : 0
|
|
568
|
+
);
|
|
569
|
+
const currentErrorRate = metrics.requests.total > 0
|
|
570
|
+
? metrics.requests.failed / metrics.requests.total
|
|
571
|
+
: 0;
|
|
572
|
+
this.checkMetricAnomaly(
|
|
573
|
+
'errorRate',
|
|
574
|
+
currentErrorRate,
|
|
575
|
+
errorRates,
|
|
576
|
+
'Error rate spike detected'
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Check if a metric value is anomalous
|
|
582
|
+
*/
|
|
583
|
+
private checkMetricAnomaly(
|
|
584
|
+
metricName: string,
|
|
585
|
+
currentValue: number,
|
|
586
|
+
historicalValues: number[],
|
|
587
|
+
description: string
|
|
588
|
+
): void {
|
|
589
|
+
if (historicalValues.length < 5) return;
|
|
590
|
+
|
|
591
|
+
const mean = historicalValues.reduce((a, b) => a + b, 0) / historicalValues.length;
|
|
592
|
+
const variance = historicalValues.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / historicalValues.length;
|
|
593
|
+
const standardDeviation = Math.sqrt(variance);
|
|
594
|
+
|
|
595
|
+
// Calculate z-score
|
|
596
|
+
const zScore = Math.abs((currentValue - mean) / standardDeviation);
|
|
597
|
+
|
|
598
|
+
// Determine sensitivity threshold
|
|
599
|
+
let threshold = 2; // Default for medium sensitivity
|
|
600
|
+
if (this.config.sensitivityLevel === 'low') threshold = 3;
|
|
601
|
+
if (this.config.sensitivityLevel === 'high') threshold = 1.5;
|
|
602
|
+
|
|
603
|
+
if (zScore > threshold) {
|
|
604
|
+
const deviation = ((currentValue - mean) / mean) * 100;
|
|
605
|
+
|
|
606
|
+
let severity: 'minor' | 'moderate' | 'major' | 'critical' = 'minor';
|
|
607
|
+
if (zScore > 4) severity = 'critical';
|
|
608
|
+
else if (zScore > 3) severity = 'major';
|
|
609
|
+
else if (zScore > 2.5) severity = 'moderate';
|
|
610
|
+
|
|
611
|
+
const anomaly: PerformanceAnomaly = {
|
|
612
|
+
timestamp: Date.now(),
|
|
613
|
+
metric: metricName,
|
|
614
|
+
expectedValue: mean,
|
|
615
|
+
actualValue: currentValue,
|
|
616
|
+
deviation,
|
|
617
|
+
severity,
|
|
618
|
+
possibleCauses: this.generatePossibleCauses(metricName, currentValue > mean)
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
this.detectedAnomalies.push(anomaly);
|
|
622
|
+
|
|
623
|
+
// Limit anomaly history
|
|
624
|
+
if (this.detectedAnomalies.length > 100) {
|
|
625
|
+
this.detectedAnomalies = this.detectedAnomalies.slice(-50);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Generate possible causes for anomalies
|
|
632
|
+
*/
|
|
633
|
+
private generatePossibleCauses(metricName: string, isIncrease: boolean): string[] {
|
|
634
|
+
const causes: string[] = [];
|
|
635
|
+
|
|
636
|
+
if (metricName === 'responseTime' && isIncrease) {
|
|
637
|
+
causes.push('High server load', 'Database performance issues', 'Network latency', 'Cache miss increase');
|
|
638
|
+
} else if (metricName === 'cacheHitRate' && !isIncrease) {
|
|
639
|
+
causes.push('Cache invalidation event', 'New data requests', 'Cache size limit reached', 'TTL expiration');
|
|
640
|
+
} else if (metricName === 'errorRate' && isIncrease) {
|
|
641
|
+
causes.push('WordPress site issues', 'Authentication problems', 'Network connectivity', 'Plugin conflicts');
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
return causes;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Create benchmark comparison
|
|
649
|
+
*/
|
|
650
|
+
private createBenchmarkComparison(
|
|
651
|
+
category: string,
|
|
652
|
+
currentValue: number,
|
|
653
|
+
benchmarks: any,
|
|
654
|
+
higherIsBetter: boolean
|
|
655
|
+
): BenchmarkComparison {
|
|
656
|
+
let status: 'excellent' | 'good' | 'average' | 'below_average' | 'poor' = 'poor';
|
|
657
|
+
let percentile = 0;
|
|
658
|
+
let improvement = 0;
|
|
659
|
+
|
|
660
|
+
if (higherIsBetter) {
|
|
661
|
+
if (currentValue >= benchmarks.excellent) status = 'excellent';
|
|
662
|
+
else if (currentValue >= benchmarks.good) status = 'good';
|
|
663
|
+
else if (currentValue >= benchmarks.average) status = 'average';
|
|
664
|
+
else if (currentValue >= benchmarks.below_average) status = 'below_average';
|
|
665
|
+
|
|
666
|
+
// Calculate improvement needed
|
|
667
|
+
if (status !== 'excellent') {
|
|
668
|
+
const nextTier = status === 'good' ? benchmarks.excellent :
|
|
669
|
+
status === 'average' ? benchmarks.good :
|
|
670
|
+
status === 'below_average' ? benchmarks.average :
|
|
671
|
+
benchmarks.below_average;
|
|
672
|
+
improvement = nextTier - currentValue;
|
|
673
|
+
}
|
|
674
|
+
} else {
|
|
675
|
+
if (currentValue <= benchmarks.excellent) status = 'excellent';
|
|
676
|
+
else if (currentValue <= benchmarks.good) status = 'good';
|
|
677
|
+
else if (currentValue <= benchmarks.average) status = 'average';
|
|
678
|
+
else if (currentValue <= benchmarks.below_average) status = 'below_average';
|
|
679
|
+
|
|
680
|
+
// Calculate improvement needed
|
|
681
|
+
if (status !== 'excellent') {
|
|
682
|
+
const nextTier = status === 'good' ? benchmarks.excellent :
|
|
683
|
+
status === 'average' ? benchmarks.good :
|
|
684
|
+
status === 'below_average' ? benchmarks.average :
|
|
685
|
+
benchmarks.below_average;
|
|
686
|
+
improvement = currentValue - nextTier;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Calculate percentile (simplified)
|
|
691
|
+
percentile = status === 'excellent' ? 95 :
|
|
692
|
+
status === 'good' ? 80 :
|
|
693
|
+
status === 'average' ? 60 :
|
|
694
|
+
status === 'below_average' ? 30 : 10;
|
|
695
|
+
|
|
696
|
+
return {
|
|
697
|
+
category,
|
|
698
|
+
currentValue,
|
|
699
|
+
benchmarkValue: benchmarks.excellent,
|
|
700
|
+
percentile,
|
|
701
|
+
status,
|
|
702
|
+
improvement
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Get current value for a metric
|
|
708
|
+
*/
|
|
709
|
+
private getCurrentMetricValue(metricName: string): number {
|
|
710
|
+
const current = this.collector.collectCurrentMetrics();
|
|
711
|
+
|
|
712
|
+
switch (metricName) {
|
|
713
|
+
case 'responseTime': return current.requests.averageResponseTime;
|
|
714
|
+
case 'cacheHitRate': return current.cache.hitRate;
|
|
715
|
+
case 'errorRate': return current.requests.total > 0 ? current.requests.failed / current.requests.total : 0;
|
|
716
|
+
case 'memoryUsage': return current.system.memoryUsage;
|
|
717
|
+
case 'requestVolume': return current.requests.requestsPerSecond;
|
|
718
|
+
default: return 0;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Calculate overall performance score
|
|
724
|
+
*/
|
|
725
|
+
private calculatePerformanceScore(metrics: PerformanceMetrics): number {
|
|
726
|
+
let score = 100;
|
|
727
|
+
|
|
728
|
+
// Response time (30% weight)
|
|
729
|
+
if (metrics.requests.averageResponseTime > 2000) score -= 30;
|
|
730
|
+
else if (metrics.requests.averageResponseTime > 1000) score -= 15;
|
|
731
|
+
else if (metrics.requests.averageResponseTime > 500) score -= 5;
|
|
732
|
+
|
|
733
|
+
// Error rate (25% weight)
|
|
734
|
+
const errorRate = metrics.requests.total > 0 ? metrics.requests.failed / metrics.requests.total : 0;
|
|
735
|
+
if (errorRate > 0.05) score -= 25;
|
|
736
|
+
else if (errorRate > 0.02) score -= 15;
|
|
737
|
+
else if (errorRate > 0.01) score -= 5;
|
|
738
|
+
|
|
739
|
+
// Cache performance (25% weight)
|
|
740
|
+
if (metrics.cache.hitRate < 0.5) score -= 25;
|
|
741
|
+
else if (metrics.cache.hitRate < 0.7) score -= 15;
|
|
742
|
+
else if (metrics.cache.hitRate < 0.85) score -= 5;
|
|
743
|
+
|
|
744
|
+
// System resources (20% weight)
|
|
745
|
+
if (metrics.system.memoryUsage > 90) score -= 20;
|
|
746
|
+
else if (metrics.system.memoryUsage > 80) score -= 10;
|
|
747
|
+
else if (metrics.system.memoryUsage > 70) score -= 5;
|
|
748
|
+
|
|
749
|
+
return Math.max(0, score);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Calculate overall health status
|
|
754
|
+
*/
|
|
755
|
+
private calculateOverallHealth(score: number): string {
|
|
756
|
+
if (score >= 90) return 'excellent';
|
|
757
|
+
if (score >= 75) return 'good';
|
|
758
|
+
if (score >= 60) return 'fair';
|
|
759
|
+
if (score >= 40) return 'poor';
|
|
760
|
+
return 'critical';
|
|
761
|
+
}
|
|
762
|
+
}
|