@delorenj/mcp-server-trello 1.2.0 → 1.5.1
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 +383 -373
- package/build/health/health-endpoints.d.ts +131 -0
- package/build/health/health-endpoints.js +476 -0
- package/build/health/health-endpoints.js.map +1 -0
- package/build/health/health-monitor.d.ts +136 -0
- package/build/health/health-monitor.js +507 -0
- package/build/health/health-monitor.js.map +1 -0
- package/build/index.js +756 -1
- package/build/index.js.map +1 -1
- package/build/trello-client.d.ts +14 -1
- package/build/trello-client.js +164 -68
- package/build/trello-client.js.map +1 -1
- package/build/types.d.ts +2 -2
- package/package.json +12 -27
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { TrelloClient } from '../trello-client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Health status levels for our magnificent Trello organism
|
|
4
|
+
*/
|
|
5
|
+
export declare enum HealthStatus {
|
|
6
|
+
HEALTHY = "healthy",
|
|
7
|
+
DEGRADED = "degraded",
|
|
8
|
+
CRITICAL = "critical",
|
|
9
|
+
UNKNOWN = "unknown"
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Individual health check result
|
|
13
|
+
*/
|
|
14
|
+
export interface HealthCheck {
|
|
15
|
+
name: string;
|
|
16
|
+
status: HealthStatus;
|
|
17
|
+
message: string;
|
|
18
|
+
duration_ms: number;
|
|
19
|
+
timestamp: string;
|
|
20
|
+
metadata?: Record<string, any>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Complete system health report
|
|
24
|
+
*/
|
|
25
|
+
export interface SystemHealthReport {
|
|
26
|
+
overall_status: HealthStatus;
|
|
27
|
+
timestamp: string;
|
|
28
|
+
checks: HealthCheck[];
|
|
29
|
+
recommendations: string[];
|
|
30
|
+
repair_available: boolean;
|
|
31
|
+
uptime_ms: number;
|
|
32
|
+
performance_metrics: {
|
|
33
|
+
avg_response_time_ms: number;
|
|
34
|
+
success_rate_percent: number;
|
|
35
|
+
rate_limit_utilization_percent: number;
|
|
36
|
+
requests_per_minute: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The magnificent HEALTH MONITORING system for our Trello MCP organism!
|
|
41
|
+
*
|
|
42
|
+
* This class performs comprehensive cardiovascular diagnostics to ensure
|
|
43
|
+
* our digital creature remains healthy and happy. It's like having a
|
|
44
|
+
* personal physician for your API! 🩺
|
|
45
|
+
*
|
|
46
|
+
* Features include:
|
|
47
|
+
* - Real-time health status monitoring
|
|
48
|
+
* - Performance metrics tracking
|
|
49
|
+
* - Rate limit utilization analysis
|
|
50
|
+
* - Automatic repair recommendations
|
|
51
|
+
* - Detailed diagnostic reporting
|
|
52
|
+
*/
|
|
53
|
+
export declare class TrelloHealthMonitor {
|
|
54
|
+
private performanceTracker;
|
|
55
|
+
private lastHealthCheck?;
|
|
56
|
+
private readonly trelloClient;
|
|
57
|
+
private rateLimiter;
|
|
58
|
+
constructor(trelloClient: TrelloClient);
|
|
59
|
+
/**
|
|
60
|
+
* Get comprehensive system health status
|
|
61
|
+
* This is the main cardiovascular examination! 🫀
|
|
62
|
+
*/
|
|
63
|
+
getSystemHealth(detailed?: boolean): Promise<SystemHealthReport>;
|
|
64
|
+
/**
|
|
65
|
+
* Check basic Trello API connectivity
|
|
66
|
+
*/
|
|
67
|
+
private checkTrelloApiConnectivity;
|
|
68
|
+
/**
|
|
69
|
+
* Check if we can access the active board
|
|
70
|
+
*/
|
|
71
|
+
private checkBoardAccess;
|
|
72
|
+
/**
|
|
73
|
+
* Check rate limiter health and utilization
|
|
74
|
+
*/
|
|
75
|
+
private checkRateLimitHealth;
|
|
76
|
+
/**
|
|
77
|
+
* Check performance metrics health
|
|
78
|
+
*/
|
|
79
|
+
private checkPerformanceMetrics;
|
|
80
|
+
/**
|
|
81
|
+
* Check list operations (detailed check)
|
|
82
|
+
*/
|
|
83
|
+
private checkListOperations;
|
|
84
|
+
/**
|
|
85
|
+
* Check card operations (detailed check)
|
|
86
|
+
*/
|
|
87
|
+
private checkCardOperations;
|
|
88
|
+
/**
|
|
89
|
+
* Check checklist operations (detailed check)
|
|
90
|
+
*/
|
|
91
|
+
private checkChecklistOperations;
|
|
92
|
+
/**
|
|
93
|
+
* Check workspace access (detailed check)
|
|
94
|
+
*/
|
|
95
|
+
private checkWorkspaceAccess;
|
|
96
|
+
/**
|
|
97
|
+
* Calculate overall system health status
|
|
98
|
+
*/
|
|
99
|
+
private calculateOverallStatus;
|
|
100
|
+
/**
|
|
101
|
+
* Generate health-based recommendations
|
|
102
|
+
*/
|
|
103
|
+
private generateRecommendations;
|
|
104
|
+
/**
|
|
105
|
+
* Check if repair functionality is available
|
|
106
|
+
*/
|
|
107
|
+
private isRepairAvailable;
|
|
108
|
+
/**
|
|
109
|
+
* Create a standardized error check result
|
|
110
|
+
*/
|
|
111
|
+
private createErrorCheck;
|
|
112
|
+
/**
|
|
113
|
+
* Record performance metrics for tracking
|
|
114
|
+
*/
|
|
115
|
+
private recordPerformanceMetric;
|
|
116
|
+
/**
|
|
117
|
+
* Calculate comprehensive performance metrics
|
|
118
|
+
*/
|
|
119
|
+
private calculatePerformanceMetrics;
|
|
120
|
+
/**
|
|
121
|
+
* Calculate rate limit utilization (approximation)
|
|
122
|
+
*/
|
|
123
|
+
private calculateRateLimitUtilization;
|
|
124
|
+
/**
|
|
125
|
+
* Categorize response times for reporting
|
|
126
|
+
*/
|
|
127
|
+
private categorizeResponseTime;
|
|
128
|
+
/**
|
|
129
|
+
* Start background performance monitoring
|
|
130
|
+
*/
|
|
131
|
+
private startPerformanceMonitoring;
|
|
132
|
+
/**
|
|
133
|
+
* Get the last health check result
|
|
134
|
+
*/
|
|
135
|
+
getLastHealthCheck(): SystemHealthReport | undefined;
|
|
136
|
+
}
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { performance } from 'perf_hooks';
|
|
2
|
+
/**
|
|
3
|
+
* Health status levels for our magnificent Trello organism
|
|
4
|
+
*/
|
|
5
|
+
export var HealthStatus;
|
|
6
|
+
(function (HealthStatus) {
|
|
7
|
+
HealthStatus["HEALTHY"] = "healthy";
|
|
8
|
+
HealthStatus["DEGRADED"] = "degraded";
|
|
9
|
+
HealthStatus["CRITICAL"] = "critical";
|
|
10
|
+
HealthStatus["UNKNOWN"] = "unknown";
|
|
11
|
+
})(HealthStatus || (HealthStatus = {}));
|
|
12
|
+
/**
|
|
13
|
+
* The magnificent HEALTH MONITORING system for our Trello MCP organism!
|
|
14
|
+
*
|
|
15
|
+
* This class performs comprehensive cardiovascular diagnostics to ensure
|
|
16
|
+
* our digital creature remains healthy and happy. It's like having a
|
|
17
|
+
* personal physician for your API! 🩺
|
|
18
|
+
*
|
|
19
|
+
* Features include:
|
|
20
|
+
* - Real-time health status monitoring
|
|
21
|
+
* - Performance metrics tracking
|
|
22
|
+
* - Rate limit utilization analysis
|
|
23
|
+
* - Automatic repair recommendations
|
|
24
|
+
* - Detailed diagnostic reporting
|
|
25
|
+
*/
|
|
26
|
+
export class TrelloHealthMonitor {
|
|
27
|
+
constructor(trelloClient) {
|
|
28
|
+
this.trelloClient = trelloClient;
|
|
29
|
+
this.performanceTracker = {
|
|
30
|
+
requests: [],
|
|
31
|
+
startTime: Date.now()
|
|
32
|
+
};
|
|
33
|
+
// Start monitoring performance in the background
|
|
34
|
+
this.startPerformanceMonitoring();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get comprehensive system health status
|
|
38
|
+
* This is the main cardiovascular examination! 🫀
|
|
39
|
+
*/
|
|
40
|
+
async getSystemHealth(detailed = false) {
|
|
41
|
+
const startTime = performance.now();
|
|
42
|
+
const checks = [];
|
|
43
|
+
// Run all health checks in parallel for maximum efficiency
|
|
44
|
+
const checkPromises = [
|
|
45
|
+
this.checkTrelloApiConnectivity(),
|
|
46
|
+
this.checkBoardAccess(),
|
|
47
|
+
this.checkRateLimitHealth(),
|
|
48
|
+
this.checkPerformanceMetrics()
|
|
49
|
+
];
|
|
50
|
+
if (detailed) {
|
|
51
|
+
checkPromises.push(this.checkListOperations(), this.checkCardOperations(), this.checkChecklistOperations(), this.checkWorkspaceAccess());
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const checkResults = await Promise.all(checkPromises);
|
|
55
|
+
checks.push(...checkResults);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// If parallel execution fails, run checks sequentially
|
|
59
|
+
checks.push(await this.createErrorCheck('parallel_execution', error));
|
|
60
|
+
}
|
|
61
|
+
// Calculate overall status
|
|
62
|
+
const overallStatus = this.calculateOverallStatus(checks);
|
|
63
|
+
// Generate recommendations
|
|
64
|
+
const recommendations = this.generateRecommendations(checks, overallStatus);
|
|
65
|
+
// Create health report
|
|
66
|
+
const report = {
|
|
67
|
+
overall_status: overallStatus,
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
checks,
|
|
70
|
+
recommendations,
|
|
71
|
+
repair_available: this.isRepairAvailable(checks),
|
|
72
|
+
uptime_ms: Date.now() - this.performanceTracker.startTime,
|
|
73
|
+
performance_metrics: this.calculatePerformanceMetrics()
|
|
74
|
+
};
|
|
75
|
+
this.lastHealthCheck = report;
|
|
76
|
+
return report;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check basic Trello API connectivity
|
|
80
|
+
*/
|
|
81
|
+
async checkTrelloApiConnectivity() {
|
|
82
|
+
const startTime = performance.now();
|
|
83
|
+
const checkName = 'trello_api_connectivity';
|
|
84
|
+
try {
|
|
85
|
+
// Simple "me" endpoint check - lowest impact way to verify connectivity
|
|
86
|
+
await this.trelloClient.listBoards();
|
|
87
|
+
const duration = performance.now() - startTime;
|
|
88
|
+
this.recordPerformanceMetric(duration, true);
|
|
89
|
+
return {
|
|
90
|
+
name: checkName,
|
|
91
|
+
status: HealthStatus.HEALTHY,
|
|
92
|
+
message: 'Trello API connectivity is excellent',
|
|
93
|
+
duration_ms: Math.round(duration),
|
|
94
|
+
timestamp: new Date().toISOString(),
|
|
95
|
+
metadata: {
|
|
96
|
+
endpoint: '/members/me/boards',
|
|
97
|
+
response_time_category: this.categorizeResponseTime(duration)
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
const duration = performance.now() - startTime;
|
|
103
|
+
this.recordPerformanceMetric(duration, false);
|
|
104
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if we can access the active board
|
|
109
|
+
*/
|
|
110
|
+
async checkBoardAccess() {
|
|
111
|
+
const startTime = performance.now();
|
|
112
|
+
const checkName = 'board_access';
|
|
113
|
+
try {
|
|
114
|
+
const boardId = this.trelloClient.activeBoardId;
|
|
115
|
+
if (!boardId) {
|
|
116
|
+
return {
|
|
117
|
+
name: checkName,
|
|
118
|
+
status: HealthStatus.DEGRADED,
|
|
119
|
+
message: 'No active board configured',
|
|
120
|
+
duration_ms: Math.round(performance.now() - startTime),
|
|
121
|
+
timestamp: new Date().toISOString(),
|
|
122
|
+
metadata: {
|
|
123
|
+
suggestion: 'Set an active board using set_active_board tool'
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const board = await this.trelloClient.getBoardById(boardId);
|
|
128
|
+
const duration = performance.now() - startTime;
|
|
129
|
+
this.recordPerformanceMetric(duration, true);
|
|
130
|
+
return {
|
|
131
|
+
name: checkName,
|
|
132
|
+
status: board.closed ? HealthStatus.CRITICAL : HealthStatus.HEALTHY,
|
|
133
|
+
message: board.closed ? 'Active board is closed/archived' : `Board "${board.name}" is accessible`,
|
|
134
|
+
duration_ms: Math.round(duration),
|
|
135
|
+
timestamp: new Date().toISOString(),
|
|
136
|
+
metadata: {
|
|
137
|
+
board_id: board.id,
|
|
138
|
+
board_name: board.name,
|
|
139
|
+
board_closed: board.closed,
|
|
140
|
+
board_url: board.url
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const duration = performance.now() - startTime;
|
|
146
|
+
this.recordPerformanceMetric(duration, false);
|
|
147
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Check rate limiter health and utilization
|
|
152
|
+
*/
|
|
153
|
+
async checkRateLimitHealth() {
|
|
154
|
+
const startTime = performance.now();
|
|
155
|
+
const checkName = 'rate_limit_health';
|
|
156
|
+
try {
|
|
157
|
+
// Get rate limiter from client (this is a bit hacky but necessary)
|
|
158
|
+
// In a real implementation, we'd expose this properly from TrelloClient
|
|
159
|
+
const rateLimiterInfo = {
|
|
160
|
+
can_make_request: true, // We'll approximate this
|
|
161
|
+
utilization_percent: this.calculateRateLimitUtilization()
|
|
162
|
+
};
|
|
163
|
+
const duration = performance.now() - startTime;
|
|
164
|
+
let status = HealthStatus.HEALTHY;
|
|
165
|
+
let message = 'Rate limiting is functioning optimally';
|
|
166
|
+
if (rateLimiterInfo.utilization_percent > 80) {
|
|
167
|
+
status = HealthStatus.DEGRADED;
|
|
168
|
+
message = 'High rate limit utilization detected';
|
|
169
|
+
}
|
|
170
|
+
else if (rateLimiterInfo.utilization_percent > 95) {
|
|
171
|
+
status = HealthStatus.CRITICAL;
|
|
172
|
+
message = 'Rate limit near exhaustion';
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
name: checkName,
|
|
176
|
+
status,
|
|
177
|
+
message,
|
|
178
|
+
duration_ms: Math.round(duration),
|
|
179
|
+
timestamp: new Date().toISOString(),
|
|
180
|
+
metadata: {
|
|
181
|
+
utilization_percent: rateLimiterInfo.utilization_percent,
|
|
182
|
+
can_make_request: rateLimiterInfo.can_make_request,
|
|
183
|
+
trello_limits: {
|
|
184
|
+
api_key_limit: '300 requests / 10 seconds',
|
|
185
|
+
token_limit: '100 requests / 10 seconds'
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
const duration = performance.now() - startTime;
|
|
192
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Check performance metrics health
|
|
197
|
+
*/
|
|
198
|
+
async checkPerformanceMetrics() {
|
|
199
|
+
const startTime = performance.now();
|
|
200
|
+
const checkName = 'performance_metrics';
|
|
201
|
+
try {
|
|
202
|
+
const metrics = this.calculatePerformanceMetrics();
|
|
203
|
+
const duration = performance.now() - startTime;
|
|
204
|
+
let status = HealthStatus.HEALTHY;
|
|
205
|
+
let message = 'Performance metrics are excellent';
|
|
206
|
+
if (metrics.avg_response_time_ms > 2000) {
|
|
207
|
+
status = HealthStatus.DEGRADED;
|
|
208
|
+
message = 'Slower than optimal response times detected';
|
|
209
|
+
}
|
|
210
|
+
else if (metrics.success_rate_percent < 95) {
|
|
211
|
+
status = HealthStatus.CRITICAL;
|
|
212
|
+
message = 'Low success rate detected';
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
name: checkName,
|
|
216
|
+
status,
|
|
217
|
+
message,
|
|
218
|
+
duration_ms: Math.round(duration),
|
|
219
|
+
timestamp: new Date().toISOString(),
|
|
220
|
+
metadata: {
|
|
221
|
+
...metrics,
|
|
222
|
+
total_requests: this.performanceTracker.requests.length
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
const duration = performance.now() - startTime;
|
|
228
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Check list operations (detailed check)
|
|
233
|
+
*/
|
|
234
|
+
async checkListOperations() {
|
|
235
|
+
const startTime = performance.now();
|
|
236
|
+
const checkName = 'list_operations';
|
|
237
|
+
try {
|
|
238
|
+
const lists = await this.trelloClient.getLists();
|
|
239
|
+
const duration = performance.now() - startTime;
|
|
240
|
+
this.recordPerformanceMetric(duration, true);
|
|
241
|
+
return {
|
|
242
|
+
name: checkName,
|
|
243
|
+
status: HealthStatus.HEALTHY,
|
|
244
|
+
message: `Successfully retrieved ${lists.length} lists`,
|
|
245
|
+
duration_ms: Math.round(duration),
|
|
246
|
+
timestamp: new Date().toISOString(),
|
|
247
|
+
metadata: {
|
|
248
|
+
total_lists: lists.length,
|
|
249
|
+
open_lists: lists.filter(l => !l.closed).length,
|
|
250
|
+
closed_lists: lists.filter(l => l.closed).length
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
const duration = performance.now() - startTime;
|
|
256
|
+
this.recordPerformanceMetric(duration, false);
|
|
257
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Check card operations (detailed check)
|
|
262
|
+
*/
|
|
263
|
+
async checkCardOperations() {
|
|
264
|
+
const startTime = performance.now();
|
|
265
|
+
const checkName = 'card_operations';
|
|
266
|
+
try {
|
|
267
|
+
const myCards = await this.trelloClient.getMyCards();
|
|
268
|
+
const duration = performance.now() - startTime;
|
|
269
|
+
this.recordPerformanceMetric(duration, true);
|
|
270
|
+
return {
|
|
271
|
+
name: checkName,
|
|
272
|
+
status: HealthStatus.HEALTHY,
|
|
273
|
+
message: `Successfully retrieved ${myCards.length} user cards`,
|
|
274
|
+
duration_ms: Math.round(duration),
|
|
275
|
+
timestamp: new Date().toISOString(),
|
|
276
|
+
metadata: {
|
|
277
|
+
total_cards: myCards.length,
|
|
278
|
+
open_cards: myCards.filter(c => !c.closed).length,
|
|
279
|
+
closed_cards: myCards.filter(c => c.closed).length
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
const duration = performance.now() - startTime;
|
|
285
|
+
this.recordPerformanceMetric(duration, false);
|
|
286
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Check checklist operations (detailed check)
|
|
291
|
+
*/
|
|
292
|
+
async checkChecklistOperations() {
|
|
293
|
+
const startTime = performance.now();
|
|
294
|
+
const checkName = 'checklist_operations';
|
|
295
|
+
try {
|
|
296
|
+
// Try to get acceptance criteria as a test
|
|
297
|
+
const criteria = await this.trelloClient.getAcceptanceCriteria();
|
|
298
|
+
const duration = performance.now() - startTime;
|
|
299
|
+
this.recordPerformanceMetric(duration, true);
|
|
300
|
+
return {
|
|
301
|
+
name: checkName,
|
|
302
|
+
status: HealthStatus.HEALTHY,
|
|
303
|
+
message: `Checklist operations functioning (${criteria.length} acceptance criteria found)`,
|
|
304
|
+
duration_ms: Math.round(duration),
|
|
305
|
+
timestamp: new Date().toISOString(),
|
|
306
|
+
metadata: {
|
|
307
|
+
acceptance_criteria_count: criteria.length,
|
|
308
|
+
completed_items: criteria.filter(item => item.complete).length
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
const duration = performance.now() - startTime;
|
|
314
|
+
this.recordPerformanceMetric(duration, false);
|
|
315
|
+
// Checklist failure might not be critical if it's just missing checklists
|
|
316
|
+
const isConfigError = error instanceof Error &&
|
|
317
|
+
(error.message.includes('not found') || error.message.includes('No board ID'));
|
|
318
|
+
return this.createErrorCheck(checkName, error, duration, isConfigError ? HealthStatus.DEGRADED : HealthStatus.CRITICAL);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Check workspace access (detailed check)
|
|
323
|
+
*/
|
|
324
|
+
async checkWorkspaceAccess() {
|
|
325
|
+
const startTime = performance.now();
|
|
326
|
+
const checkName = 'workspace_access';
|
|
327
|
+
try {
|
|
328
|
+
const workspaces = await this.trelloClient.listWorkspaces();
|
|
329
|
+
const duration = performance.now() - startTime;
|
|
330
|
+
this.recordPerformanceMetric(duration, true);
|
|
331
|
+
return {
|
|
332
|
+
name: checkName,
|
|
333
|
+
status: HealthStatus.HEALTHY,
|
|
334
|
+
message: `Access to ${workspaces.length} workspaces confirmed`,
|
|
335
|
+
duration_ms: Math.round(duration),
|
|
336
|
+
timestamp: new Date().toISOString(),
|
|
337
|
+
metadata: {
|
|
338
|
+
total_workspaces: workspaces.length,
|
|
339
|
+
active_workspace_id: this.trelloClient.activeWorkspaceId,
|
|
340
|
+
workspace_names: workspaces.map(w => w.displayName)
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
const duration = performance.now() - startTime;
|
|
346
|
+
this.recordPerformanceMetric(duration, false);
|
|
347
|
+
return this.createErrorCheck(checkName, error, duration);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Calculate overall system health status
|
|
352
|
+
*/
|
|
353
|
+
calculateOverallStatus(checks) {
|
|
354
|
+
if (checks.some(c => c.status === HealthStatus.CRITICAL)) {
|
|
355
|
+
return HealthStatus.CRITICAL;
|
|
356
|
+
}
|
|
357
|
+
if (checks.some(c => c.status === HealthStatus.DEGRADED)) {
|
|
358
|
+
return HealthStatus.DEGRADED;
|
|
359
|
+
}
|
|
360
|
+
if (checks.every(c => c.status === HealthStatus.HEALTHY)) {
|
|
361
|
+
return HealthStatus.HEALTHY;
|
|
362
|
+
}
|
|
363
|
+
return HealthStatus.UNKNOWN;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Generate health-based recommendations
|
|
367
|
+
*/
|
|
368
|
+
generateRecommendations(checks, overallStatus) {
|
|
369
|
+
const recommendations = [];
|
|
370
|
+
// Check for specific issues and provide targeted advice
|
|
371
|
+
const boardCheck = checks.find(c => c.name === 'board_access');
|
|
372
|
+
if (boardCheck?.status === HealthStatus.DEGRADED && boardCheck.metadata?.suggestion) {
|
|
373
|
+
recommendations.push(boardCheck.metadata.suggestion);
|
|
374
|
+
}
|
|
375
|
+
const rateLimitCheck = checks.find(c => c.name === 'rate_limit_health');
|
|
376
|
+
if (rateLimitCheck?.status === HealthStatus.DEGRADED) {
|
|
377
|
+
recommendations.push('Consider implementing request throttling or caching to reduce API usage');
|
|
378
|
+
}
|
|
379
|
+
const performanceCheck = checks.find(c => c.name === 'performance_metrics');
|
|
380
|
+
if (performanceCheck?.status === HealthStatus.DEGRADED) {
|
|
381
|
+
recommendations.push('Investigate slow response times - consider network conditions or API load');
|
|
382
|
+
}
|
|
383
|
+
// Overall status recommendations
|
|
384
|
+
if (overallStatus === HealthStatus.HEALTHY) {
|
|
385
|
+
recommendations.push('All systems operating normally - maintain current configuration');
|
|
386
|
+
}
|
|
387
|
+
else if (overallStatus === HealthStatus.CRITICAL) {
|
|
388
|
+
recommendations.push('Immediate attention required - check error logs and connectivity');
|
|
389
|
+
}
|
|
390
|
+
return recommendations.length > 0 ? recommendations : ['System assessment complete - no specific recommendations'];
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Check if repair functionality is available
|
|
394
|
+
*/
|
|
395
|
+
isRepairAvailable(checks) {
|
|
396
|
+
// Simple heuristic: repair available if we have degraded but not critical issues
|
|
397
|
+
return checks.some(c => c.status === HealthStatus.DEGRADED) &&
|
|
398
|
+
!checks.some(c => c.status === HealthStatus.CRITICAL);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Create a standardized error check result
|
|
402
|
+
*/
|
|
403
|
+
createErrorCheck(checkName, error, duration, status = HealthStatus.CRITICAL) {
|
|
404
|
+
let message = 'Unknown error occurred';
|
|
405
|
+
let errorCode;
|
|
406
|
+
if (error instanceof Error) {
|
|
407
|
+
message = error.message;
|
|
408
|
+
}
|
|
409
|
+
if (error && typeof error === 'object' && 'response' in error) {
|
|
410
|
+
const axiosError = error;
|
|
411
|
+
errorCode = axiosError.response?.status?.toString();
|
|
412
|
+
message = `HTTP ${axiosError.response?.status}: ${axiosError.message}`;
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
name: checkName,
|
|
416
|
+
status,
|
|
417
|
+
message,
|
|
418
|
+
duration_ms: Math.round(duration || 0),
|
|
419
|
+
timestamp: new Date().toISOString(),
|
|
420
|
+
metadata: {
|
|
421
|
+
error_type: error?.constructor?.name || 'Unknown',
|
|
422
|
+
error_code: errorCode,
|
|
423
|
+
error_details: error instanceof Error ? error.stack : undefined
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Record performance metrics for tracking
|
|
429
|
+
*/
|
|
430
|
+
recordPerformanceMetric(duration, success) {
|
|
431
|
+
const now = Date.now();
|
|
432
|
+
this.performanceTracker.requests.push({ timestamp: now, duration, success });
|
|
433
|
+
// Keep only last 100 requests to prevent memory leaks
|
|
434
|
+
if (this.performanceTracker.requests.length > 100) {
|
|
435
|
+
this.performanceTracker.requests = this.performanceTracker.requests.slice(-100);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Calculate comprehensive performance metrics
|
|
440
|
+
*/
|
|
441
|
+
calculatePerformanceMetrics() {
|
|
442
|
+
const requests = this.performanceTracker.requests;
|
|
443
|
+
if (requests.length === 0) {
|
|
444
|
+
return {
|
|
445
|
+
avg_response_time_ms: 0,
|
|
446
|
+
success_rate_percent: 100,
|
|
447
|
+
rate_limit_utilization_percent: 0,
|
|
448
|
+
requests_per_minute: 0
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
const avgResponseTime = requests.reduce((sum, r) => sum + r.duration, 0) / requests.length;
|
|
452
|
+
const successRate = (requests.filter(r => r.success).length / requests.length) * 100;
|
|
453
|
+
// Calculate requests per minute based on recent activity
|
|
454
|
+
const oneMinuteAgo = Date.now() - 60000;
|
|
455
|
+
const recentRequests = requests.filter(r => r.timestamp > oneMinuteAgo);
|
|
456
|
+
const requestsPerMinute = recentRequests.length;
|
|
457
|
+
return {
|
|
458
|
+
avg_response_time_ms: Math.round(avgResponseTime),
|
|
459
|
+
success_rate_percent: Math.round(successRate * 100) / 100,
|
|
460
|
+
rate_limit_utilization_percent: this.calculateRateLimitUtilization(),
|
|
461
|
+
requests_per_minute: requestsPerMinute
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Calculate rate limit utilization (approximation)
|
|
466
|
+
*/
|
|
467
|
+
calculateRateLimitUtilization() {
|
|
468
|
+
const requests = this.performanceTracker.requests;
|
|
469
|
+
const tenSecondsAgo = Date.now() - 10000;
|
|
470
|
+
const recentRequests = requests.filter(r => r.timestamp > tenSecondsAgo).length;
|
|
471
|
+
// Use the more restrictive limit (100 per 10 seconds for tokens)
|
|
472
|
+
return Math.min(100, (recentRequests / 100) * 100);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Categorize response times for reporting
|
|
476
|
+
*/
|
|
477
|
+
categorizeResponseTime(duration) {
|
|
478
|
+
if (duration < 200)
|
|
479
|
+
return 'excellent';
|
|
480
|
+
if (duration < 500)
|
|
481
|
+
return 'good';
|
|
482
|
+
if (duration < 1000)
|
|
483
|
+
return 'fair';
|
|
484
|
+
if (duration < 2000)
|
|
485
|
+
return 'slow';
|
|
486
|
+
return 'very_slow';
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Start background performance monitoring
|
|
490
|
+
*/
|
|
491
|
+
startPerformanceMonitoring() {
|
|
492
|
+
// Simple monitoring - in a real implementation, this might be more sophisticated
|
|
493
|
+
setInterval(() => {
|
|
494
|
+
// Clean up old metrics to prevent memory leaks
|
|
495
|
+
const fiveMinutesAgo = Date.now() - 300000;
|
|
496
|
+
this.performanceTracker.requests = this.performanceTracker.requests
|
|
497
|
+
.filter(r => r.timestamp > fiveMinutesAgo);
|
|
498
|
+
}, 60000); // Clean up every minute
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Get the last health check result
|
|
502
|
+
*/
|
|
503
|
+
getLastHealthCheck() {
|
|
504
|
+
return this.lastHealthCheck;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
//# sourceMappingURL=health-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-monitor.js","sourceRoot":"","sources":["../../src/health/health-monitor.ts"],"names":[],"mappings":"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"}
|