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,447 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real-time Metrics Collector for WordPress MCP Server
|
|
3
|
+
* Integrates with existing client and cache systems
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { PerformanceMonitor, PerformanceMetrics } from './PerformanceMonitor.js';
|
|
7
|
+
import type { CacheStats } from '../cache/CacheManager.js';
|
|
8
|
+
import type { ClientStats } from '../types/client.js';
|
|
9
|
+
|
|
10
|
+
export interface CollectorConfig {
|
|
11
|
+
enableRealTime: boolean;
|
|
12
|
+
collectInterval: number;
|
|
13
|
+
enableToolTracking: boolean;
|
|
14
|
+
enableRequestInterception: boolean;
|
|
15
|
+
enableCacheIntegration: boolean;
|
|
16
|
+
enableSystemMetrics: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface RequestMetadata {
|
|
20
|
+
toolName?: string;
|
|
21
|
+
siteId?: string;
|
|
22
|
+
endpoint: string;
|
|
23
|
+
method: string;
|
|
24
|
+
startTime: number;
|
|
25
|
+
fromCache: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ToolExecutionContext {
|
|
29
|
+
toolName: string;
|
|
30
|
+
parameters: any;
|
|
31
|
+
startTime: number;
|
|
32
|
+
siteId: string | undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Metrics Collector - Central hub for all performance data
|
|
37
|
+
*/
|
|
38
|
+
export class MetricsCollector {
|
|
39
|
+
private monitor: PerformanceMonitor;
|
|
40
|
+
private config: CollectorConfig;
|
|
41
|
+
private activeRequests: Map<string, RequestMetadata> = new Map();
|
|
42
|
+
private activeTools: Map<string, ToolExecutionContext> = new Map();
|
|
43
|
+
private clientInstances: Map<string, any> = new Map();
|
|
44
|
+
private cacheManagers: Map<string, any> = new Map();
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
monitor: PerformanceMonitor,
|
|
48
|
+
config: Partial<CollectorConfig> = {}
|
|
49
|
+
) {
|
|
50
|
+
this.monitor = monitor;
|
|
51
|
+
this.config = {
|
|
52
|
+
enableRealTime: true,
|
|
53
|
+
collectInterval: 30000, // 30 seconds
|
|
54
|
+
enableToolTracking: true,
|
|
55
|
+
enableRequestInterception: true,
|
|
56
|
+
enableCacheIntegration: true,
|
|
57
|
+
enableSystemMetrics: true,
|
|
58
|
+
...config
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (this.config.enableRealTime) {
|
|
62
|
+
this.startRealTimeCollection();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Register a WordPress client for monitoring
|
|
68
|
+
*/
|
|
69
|
+
registerClient(siteId: string, client: any): void {
|
|
70
|
+
this.clientInstances.set(siteId, client);
|
|
71
|
+
|
|
72
|
+
if (this.config.enableRequestInterception) {
|
|
73
|
+
this.interceptClientRequests(siteId, client);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Register a cache manager for monitoring
|
|
79
|
+
*/
|
|
80
|
+
registerCacheManager(siteId: string, cacheManager: any): void {
|
|
81
|
+
this.cacheManagers.set(siteId, cacheManager);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Start tracking a tool execution
|
|
86
|
+
*/
|
|
87
|
+
startToolExecution(toolName: string, parameters: any, siteId?: string): string {
|
|
88
|
+
const executionId = `${toolName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
89
|
+
|
|
90
|
+
this.activeTools.set(executionId, {
|
|
91
|
+
toolName,
|
|
92
|
+
parameters,
|
|
93
|
+
startTime: Date.now(),
|
|
94
|
+
siteId
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return executionId;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* End tool execution and record metrics
|
|
102
|
+
*/
|
|
103
|
+
endToolExecution(executionId: string, success: boolean, error?: Error): void {
|
|
104
|
+
const context = this.activeTools.get(executionId);
|
|
105
|
+
if (!context) return;
|
|
106
|
+
|
|
107
|
+
const responseTime = Date.now() - context.startTime;
|
|
108
|
+
|
|
109
|
+
// Record in performance monitor
|
|
110
|
+
this.monitor.recordRequest(responseTime, success, context.toolName);
|
|
111
|
+
|
|
112
|
+
this.activeTools.delete(executionId);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Record a raw request (bypass tool tracking)
|
|
117
|
+
*/
|
|
118
|
+
recordRawRequest(
|
|
119
|
+
responseTime: number,
|
|
120
|
+
success: boolean,
|
|
121
|
+
endpoint: string,
|
|
122
|
+
fromCache: boolean = false
|
|
123
|
+
): void {
|
|
124
|
+
this.monitor.recordRequest(responseTime, success);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Collect current metrics from all sources
|
|
129
|
+
*/
|
|
130
|
+
collectCurrentMetrics(): PerformanceMetrics {
|
|
131
|
+
// Update cache metrics from all registered cache managers
|
|
132
|
+
this.updateCacheMetrics();
|
|
133
|
+
|
|
134
|
+
// Update client metrics from all registered clients
|
|
135
|
+
this.updateClientMetrics();
|
|
136
|
+
|
|
137
|
+
// Get current metrics from monitor
|
|
138
|
+
return this.monitor.getMetrics();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get aggregated cache statistics
|
|
143
|
+
*/
|
|
144
|
+
getAggregatedCacheStats(): CacheStats {
|
|
145
|
+
const aggregated: CacheStats = {
|
|
146
|
+
hits: 0,
|
|
147
|
+
misses: 0,
|
|
148
|
+
evictions: 0,
|
|
149
|
+
totalSize: 0,
|
|
150
|
+
hitRate: 0
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
for (const [_siteId, cacheManager] of this.cacheManagers) {
|
|
154
|
+
if (cacheManager && typeof cacheManager.getStats === 'function') {
|
|
155
|
+
const stats = cacheManager.getStats();
|
|
156
|
+
aggregated.hits += stats.hits || 0;
|
|
157
|
+
aggregated.misses += stats.misses || 0;
|
|
158
|
+
aggregated.evictions += stats.evictions || 0;
|
|
159
|
+
aggregated.totalSize += stats.totalSize || 0;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Calculate overall hit rate
|
|
164
|
+
const total = aggregated.hits + aggregated.misses;
|
|
165
|
+
aggregated.hitRate = total > 0 ? aggregated.hits / total : 0;
|
|
166
|
+
|
|
167
|
+
return aggregated;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get aggregated client statistics
|
|
172
|
+
*/
|
|
173
|
+
getAggregatedClientStats(): ClientStats {
|
|
174
|
+
const aggregated: ClientStats = {
|
|
175
|
+
totalRequests: 0,
|
|
176
|
+
successfulRequests: 0,
|
|
177
|
+
failedRequests: 0,
|
|
178
|
+
averageResponseTime: 0,
|
|
179
|
+
rateLimitHits: 0,
|
|
180
|
+
authFailures: 0
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const responseTimes: number[] = [];
|
|
184
|
+
|
|
185
|
+
for (const [_siteId, client] of this.clientInstances) {
|
|
186
|
+
if (client && typeof client.getStats === 'function') {
|
|
187
|
+
const stats = client.getStats();
|
|
188
|
+
aggregated.totalRequests += stats.totalRequests || 0;
|
|
189
|
+
aggregated.successfulRequests += stats.successfulRequests || 0;
|
|
190
|
+
aggregated.failedRequests += stats.failedRequests || 0;
|
|
191
|
+
aggregated.rateLimitHits += stats.rateLimitHits || 0;
|
|
192
|
+
aggregated.authFailures += stats.authFailures || 0;
|
|
193
|
+
|
|
194
|
+
if (stats.averageResponseTime) {
|
|
195
|
+
responseTimes.push(stats.averageResponseTime);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Calculate overall average response time
|
|
201
|
+
if (responseTimes.length > 0) {
|
|
202
|
+
aggregated.averageResponseTime = responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return aggregated;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Get performance summary for specific site
|
|
210
|
+
*/
|
|
211
|
+
getSiteMetrics(siteId: string): {
|
|
212
|
+
cache?: CacheStats;
|
|
213
|
+
client?: ClientStats;
|
|
214
|
+
isActive: boolean;
|
|
215
|
+
} {
|
|
216
|
+
const result: any = { isActive: false };
|
|
217
|
+
|
|
218
|
+
const cacheManager = this.cacheManagers.get(siteId);
|
|
219
|
+
if (cacheManager && typeof cacheManager.getStats === 'function') {
|
|
220
|
+
result.cache = cacheManager.getStats();
|
|
221
|
+
result.isActive = true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const client = this.clientInstances.get(siteId);
|
|
225
|
+
if (client && typeof client.getStats === 'function') {
|
|
226
|
+
result.client = client.getStats();
|
|
227
|
+
result.isActive = true;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Generate performance comparison between sites
|
|
235
|
+
*/
|
|
236
|
+
compareSitePerformance(): {
|
|
237
|
+
sites: string[];
|
|
238
|
+
comparison: Record<string, {
|
|
239
|
+
responseTime: number;
|
|
240
|
+
cacheHitRate: number;
|
|
241
|
+
errorRate: number;
|
|
242
|
+
requestCount: number;
|
|
243
|
+
ranking: number;
|
|
244
|
+
}>;
|
|
245
|
+
bestPerforming: string;
|
|
246
|
+
worstPerforming: string;
|
|
247
|
+
} {
|
|
248
|
+
const sites = Array.from(this.clientInstances.keys());
|
|
249
|
+
const comparison: any = {};
|
|
250
|
+
const rankings: Array<{ site: string; score: number }> = [];
|
|
251
|
+
|
|
252
|
+
for (const siteId of sites) {
|
|
253
|
+
const metrics = this.getSiteMetrics(siteId);
|
|
254
|
+
|
|
255
|
+
const responseTime = metrics.client?.averageResponseTime || 0;
|
|
256
|
+
const cacheHitRate = metrics.cache?.hitRate || 0;
|
|
257
|
+
const errorRate = metrics.client
|
|
258
|
+
? (metrics.client.failedRequests / Math.max(metrics.client.totalRequests, 1))
|
|
259
|
+
: 0;
|
|
260
|
+
const requestCount = metrics.client?.totalRequests || 0;
|
|
261
|
+
|
|
262
|
+
// Calculate performance score (lower is better for response time and error rate)
|
|
263
|
+
const score = (responseTime / 1000) + (errorRate * 100) - (cacheHitRate * 50) + (requestCount * 0.001);
|
|
264
|
+
|
|
265
|
+
comparison[siteId] = {
|
|
266
|
+
responseTime,
|
|
267
|
+
cacheHitRate,
|
|
268
|
+
errorRate,
|
|
269
|
+
requestCount,
|
|
270
|
+
ranking: 0 // Will be set after sorting
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
rankings.push({ site: siteId, score });
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Sort by performance score
|
|
277
|
+
rankings.sort((a, b) => a.score - b.score);
|
|
278
|
+
|
|
279
|
+
// Assign rankings
|
|
280
|
+
rankings.forEach((item, index) => {
|
|
281
|
+
comparison[item.site].ranking = index + 1;
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
sites,
|
|
286
|
+
comparison,
|
|
287
|
+
bestPerforming: rankings[0]?.site || '',
|
|
288
|
+
worstPerforming: rankings[rankings.length - 1]?.site || ''
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Generate optimization suggestions
|
|
294
|
+
*/
|
|
295
|
+
generateOptimizationSuggestions(): {
|
|
296
|
+
critical: string[];
|
|
297
|
+
recommended: string[];
|
|
298
|
+
optional: string[];
|
|
299
|
+
} {
|
|
300
|
+
const metrics = this.collectCurrentMetrics();
|
|
301
|
+
const critical: string[] = [];
|
|
302
|
+
const recommended: string[] = [];
|
|
303
|
+
const optional: string[] = [];
|
|
304
|
+
|
|
305
|
+
// Critical issues
|
|
306
|
+
if (metrics.requests.averageResponseTime > 5000) {
|
|
307
|
+
critical.push('Response times are critically high (>5s). Enable caching immediately.');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const errorRate = metrics.requests.failed / Math.max(metrics.requests.total, 1);
|
|
311
|
+
if (errorRate > 0.1) {
|
|
312
|
+
critical.push('Error rate is critically high (>10%). Check WordPress connectivity.');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Recommended optimizations
|
|
316
|
+
if (metrics.cache.hitRate < 0.8) {
|
|
317
|
+
recommended.push('Cache hit rate is below 80%. Consider cache warming or TTL adjustment.');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (metrics.requests.averageResponseTime > 2000) {
|
|
321
|
+
recommended.push('Response times could be improved. Consider enabling more aggressive caching.');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (metrics.system.memoryUsage > 80) {
|
|
325
|
+
recommended.push('Memory usage is high. Consider increasing cache size limits or server resources.');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Optional optimizations
|
|
329
|
+
if (metrics.cache.totalSize < 100) {
|
|
330
|
+
optional.push('Cache utilization is low. Consider pre-warming with frequently accessed data.');
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (Object.keys(metrics.tools.toolUsageCount).length > 10) {
|
|
334
|
+
optional.push('Many tools are being used. Consider creating custom workflows for common operations.');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return { critical, recommended, optional };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Export detailed performance report
|
|
342
|
+
*/
|
|
343
|
+
exportDetailedReport(): {
|
|
344
|
+
timestamp: string;
|
|
345
|
+
overview: PerformanceMetrics;
|
|
346
|
+
siteComparison: any;
|
|
347
|
+
aggregatedStats: {
|
|
348
|
+
cache: CacheStats;
|
|
349
|
+
client: ClientStats;
|
|
350
|
+
};
|
|
351
|
+
optimizations: any;
|
|
352
|
+
alerts: any[];
|
|
353
|
+
} {
|
|
354
|
+
return {
|
|
355
|
+
timestamp: new Date().toISOString(),
|
|
356
|
+
overview: this.collectCurrentMetrics(),
|
|
357
|
+
siteComparison: this.compareSitePerformance(),
|
|
358
|
+
aggregatedStats: {
|
|
359
|
+
cache: this.getAggregatedCacheStats(),
|
|
360
|
+
client: this.getAggregatedClientStats()
|
|
361
|
+
},
|
|
362
|
+
optimizations: this.generateOptimizationSuggestions(),
|
|
363
|
+
alerts: this.monitor.getAlerts()
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Start real-time metric collection
|
|
369
|
+
*/
|
|
370
|
+
private startRealTimeCollection(): void {
|
|
371
|
+
setInterval(() => {
|
|
372
|
+
this.updateCacheMetrics();
|
|
373
|
+
this.updateClientMetrics();
|
|
374
|
+
}, this.config.collectInterval);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Update cache metrics in performance monitor
|
|
379
|
+
*/
|
|
380
|
+
private updateCacheMetrics(): void {
|
|
381
|
+
const aggregatedStats = this.getAggregatedCacheStats();
|
|
382
|
+
this.monitor.updateCacheMetrics(aggregatedStats);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Update client metrics in performance monitor
|
|
387
|
+
*/
|
|
388
|
+
private updateClientMetrics(): void {
|
|
389
|
+
// Client metrics are updated through request interception
|
|
390
|
+
// This method can be used for additional client-specific metrics
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Intercept client requests for automatic tracking
|
|
395
|
+
*/
|
|
396
|
+
private interceptClientRequests(siteId: string, client: any): void {
|
|
397
|
+
if (!client.request || typeof client.request !== 'function') {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const originalRequest = client.request.bind(client);
|
|
402
|
+
|
|
403
|
+
client.request = async (...args: any[]) => {
|
|
404
|
+
const startTime = Date.now();
|
|
405
|
+
const requestId = `${siteId}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
406
|
+
|
|
407
|
+
// Extract metadata
|
|
408
|
+
const metadata: RequestMetadata = {
|
|
409
|
+
siteId,
|
|
410
|
+
endpoint: args[0] || 'unknown',
|
|
411
|
+
method: args[1] || 'GET',
|
|
412
|
+
startTime,
|
|
413
|
+
fromCache: false
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
this.activeRequests.set(requestId, metadata);
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
const result = await originalRequest(...args);
|
|
420
|
+
const responseTime = Date.now() - startTime;
|
|
421
|
+
|
|
422
|
+
// Check if response came from cache
|
|
423
|
+
const _fromCache = result.cached || false;
|
|
424
|
+
|
|
425
|
+
this.monitor.recordRequest(responseTime, true);
|
|
426
|
+
this.activeRequests.delete(requestId);
|
|
427
|
+
|
|
428
|
+
return result;
|
|
429
|
+
} catch (error) {
|
|
430
|
+
const responseTime = Date.now() - startTime;
|
|
431
|
+
this.monitor.recordRequest(responseTime, false);
|
|
432
|
+
this.activeRequests.delete(requestId);
|
|
433
|
+
|
|
434
|
+
throw error;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Stop all monitoring and cleanup
|
|
441
|
+
*/
|
|
442
|
+
stop(): void {
|
|
443
|
+
this.monitor.stop();
|
|
444
|
+
this.activeRequests.clear();
|
|
445
|
+
this.activeTools.clear();
|
|
446
|
+
}
|
|
447
|
+
}
|