@aetherframework/database 1.0.9 → 1.1.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.
Files changed (44) hide show
  1. package/package.json +1 -2
  2. package/src/DatabaseManager.js +0 -565
  3. package/src/core/ConnectionManager.js +0 -351
  4. package/src/core/DatabaseFactory.js +0 -188
  5. package/src/core/MongoQueryBuilder.js +0 -576
  6. package/src/core/PluginManager.js +0 -968
  7. package/src/core/QueryBuilder.js +0 -4398
  8. package/src/core/TransactionManager.js +0 -40
  9. package/src/drivers/clickhouse-driver.js +0 -272
  10. package/src/drivers/index.js +0 -273
  11. package/src/drivers/mongodb-driver.js +0 -87
  12. package/src/drivers/mssql-driver.js +0 -117
  13. package/src/drivers/mysql-driver.js +0 -169
  14. package/src/drivers/oracle-driver.js +0 -101
  15. package/src/drivers/postgres-driver.js +0 -234
  16. package/src/drivers/redis-driver.js +0 -52
  17. package/src/drivers/sqlite-driver.js +0 -67
  18. package/src/middleware/connection-pool.js +0 -455
  19. package/src/middleware/performance-monitor.js +0 -652
  20. package/src/middleware/query-cache.js +0 -500
  21. package/src/middleware/query-logger.js +0 -262
  22. package/src/plugins/AuditPlugin.js +0 -447
  23. package/src/plugins/BasePlugin.js +0 -418
  24. package/src/plugins/BatchOperationPlugin.js +0 -165
  25. package/src/plugins/CachePlugin.js +0 -407
  26. package/src/plugins/CtePlugin.js +0 -523
  27. package/src/plugins/DistributedPlugin.js +0 -543
  28. package/src/plugins/EncryptionPlugin.js +0 -211
  29. package/src/plugins/FullTextSearchPlugin.js +0 -164
  30. package/src/plugins/GeospatialPlugin.js +0 -219
  31. package/src/plugins/GraphQLPlugin.js +0 -162
  32. package/src/plugins/HookPlugin.js +0 -211
  33. package/src/plugins/JsonPlugin.js +0 -366
  34. package/src/plugins/OptimisticLockPlugin.js +0 -374
  35. package/src/plugins/PerformancePlugin.js +0 -175
  36. package/src/plugins/ResiliencePlugin.js +0 -114
  37. package/src/plugins/ShardingPlugin.js +0 -227
  38. package/src/plugins/SoftDeletePlugin.js +0 -258
  39. package/src/plugins/SyncPlugin.js +0 -373
  40. package/src/plugins/VersioningPlugin.js +0 -314
  41. package/src/plugins/WindowFunctionPlugin.js +0 -343
  42. package/src/utils/config-loader.js +0 -632
  43. package/src/utils/error-handler.js +0 -724
  44. package/src/utils/migration-runner.js +0 -1066
@@ -1,652 +0,0 @@
1
- /**
2
- * @license MIT
3
- * Copyright (c) 2026-present AetherFramework Contributors.
4
- * SPDX-License-Identifier: MIT
5
- * @module @aetherframework/database/middleware/performance-monitor
6
- */
7
- import { EventEmitter } from 'events';
8
-
9
- class PerformanceMonitor extends EventEmitter {
10
- constructor(options = {}) {
11
- super();
12
- this.options = {
13
- enabled: options.enabled !== false,
14
- slowQueryThreshold: options.slowQueryThreshold || 1000, // ms
15
- maxQueryHistory: options.maxQueryHistory || 1000,
16
- collectMetrics: options.collectMetrics !== false,
17
- metricsInterval: options.metricsInterval || 60000, // 1 minute
18
- alertThresholds: {
19
- slowQueriesPerMinute: options.alertThresholds?.slowQueriesPerMinute || 10,
20
- errorRate: options.alertThresholds?.errorRate || 0.1, // 10%
21
- connectionErrors: options.alertThresholds?.connectionErrors || 5,
22
- ...options.alertThresholds
23
- },
24
- ...options
25
- };
26
-
27
- this.queries = [];
28
- this.slowQueries = [];
29
- this.errors = [];
30
- this.metrics = {
31
- totalQueries: 0,
32
- successfulQueries: 0,
33
- failedQueries: 0,
34
- slowQueries: 0,
35
- totalQueryTime: 0,
36
- avgQueryTime: 0,
37
- maxQueryTime: 0,
38
- minQueryTime: Infinity,
39
- connections: new Map(),
40
- alerts: []
41
- };
42
-
43
- this.startMetricsCollection();
44
- }
45
-
46
- /**
47
- * Monitor query execution
48
- * @param {Object} query - Query object
49
- * @param {Function} execute - Query execution function
50
- * @returns {Promise<Object>} Query result
51
- */
52
- async monitor(query, execute) {
53
- if (!this.options.enabled) {
54
- return execute(query);
55
- }
56
-
57
- const startTime = Date.now();
58
- const startMemory = process.memoryUsage();
59
-
60
- try {
61
- const result = await execute(query);
62
- const endTime = Date.now();
63
- const endMemory = process.memoryUsage();
64
-
65
- const duration = endTime - startTime;
66
- const memoryDiff = endMemory.heapUsed - startMemory.heapUsed;
67
-
68
- this.recordQuery(query, duration, true, null, memoryDiff);
69
-
70
- // Check for slow query
71
- if (duration > this.options.slowQueryThreshold) {
72
- this.recordSlowQuery(query, duration);
73
- this.emit('slow-query', { query, duration, threshold: this.options.slowQueryThreshold });
74
- }
75
-
76
- return result;
77
- } catch (error) {
78
- const endTime = Date.now();
79
- const duration = endTime - startTime;
80
-
81
- this.recordQuery(query, duration, false, error);
82
- this.recordError(query, error, duration);
83
-
84
- this.emit('query-error', { query, error, duration });
85
- throw error;
86
- }
87
- }
88
-
89
- /**
90
- * Record query execution
91
- * @param {Object} query - Query object
92
- * @param {number} duration - Execution duration in ms
93
- * @param {boolean} success - Whether query succeeded
94
- * @param {Error|null} error - Error object if failed
95
- * @param {number} memoryDiff - Memory difference in bytes
96
- */
97
- recordQuery(query, duration, success, error = null, memoryDiff = 0) {
98
- const queryRecord = {
99
- timestamp: new Date().toISOString(),
100
- sql: query.sql.substring(0, 200) + (query.sql.length > 200 ? '...' : ''),
101
- params: query.params,
102
- duration,
103
- success,
104
- error: error ? error.message : null,
105
- connection: query.connectionName || 'default',
106
- type: query.type || 'query',
107
- memoryDiff
108
- };
109
-
110
- // Add to query history
111
- this.queries.push(queryRecord);
112
- if (this.queries.length > this.options.maxQueryHistory) {
113
- this.queries.shift();
114
- }
115
-
116
- // Update metrics
117
- this.metrics.totalQueries++;
118
- if (success) {
119
- this.metrics.successfulQueries++;
120
- } else {
121
- this.metrics.failedQueries++;
122
- }
123
-
124
- this.metrics.totalQueryTime += duration;
125
- this.metrics.avgQueryTime = this.metrics.totalQueryTime / this.metrics.totalQueries;
126
- this.metrics.maxQueryTime = Math.max(this.metrics.maxQueryTime, duration);
127
- this.metrics.minQueryTime = Math.min(this.metrics.minQueryTime, duration);
128
-
129
- // Update connection metrics
130
- const connectionName = query.connectionName || 'default';
131
- if (!this.metrics.connections.has(connectionName)) {
132
- this.metrics.connections.set(connectionName, {
133
- totalQueries: 0,
134
- successfulQueries: 0,
135
- failedQueries: 0,
136
- totalQueryTime: 0,
137
- avgQueryTime: 0
138
- });
139
- }
140
-
141
- const connMetrics = this.metrics.connections.get(connectionName);
142
- connMetrics.totalQueries++;
143
- if (success) {
144
- connMetrics.successfulQueries++;
145
- } else {
146
- connMetrics.failedQueries++;
147
- }
148
- connMetrics.totalQueryTime += duration;
149
- connMetrics.avgQueryTime = connMetrics.totalQueryTime / connMetrics.totalQueries;
150
-
151
- this.emit('query-recorded', queryRecord);
152
- }
153
-
154
- /**
155
- * Record slow query
156
- * @param {Object} query - Query object
157
- * @param {number} duration - Execution duration in ms
158
- */
159
- recordSlowQuery(query, duration) {
160
- const slowQueryRecord = {
161
- timestamp: new Date().toISOString(),
162
- sql: query.sql.substring(0, 200) + (query.sql.length > 200 ? '...' : ''),
163
- params: query.params,
164
- duration,
165
- threshold: this.options.slowQueryThreshold,
166
- connection: query.connectionName || 'default',
167
- type: query.type || 'query'
168
- };
169
-
170
- this.slowQueries.push(slowQueryRecord);
171
- this.metrics.slowQueries++;
172
-
173
- // Check alert threshold
174
- const slowQueriesLastMinute = this.getSlowQueriesLastMinute();
175
- if (slowQueriesLastMinute > this.options.alertThresholds.slowQueriesPerMinute) {
176
- this.triggerAlert('slow-queries', {
177
- message: `High number of slow queries detected: ${slowQueriesLastMinute} in the last minute`,
178
- threshold: this.options.alertThresholds.slowQueriesPerMinute,
179
- actual: slowQueriesLastMinute,
180
- queries: this.slowQueries.slice(-10) // Last 10 slow queries
181
- });
182
- }
183
- }
184
-
185
- /**
186
- * Record error
187
- * @param {Object} query - Query object
188
- * @param {Error} error - Error object
189
- * @param {number} duration - Execution duration in ms
190
- */
191
- recordError(query, error, duration) {
192
- const errorRecord = {
193
- timestamp: new Date().toISOString(),
194
- sql: query.sql.substring(0, 200) + (query.sql.length > 200 ? '...' : ''),
195
- params: query.params,
196
- duration,
197
- error: error.message,
198
- stack: error.stack,
199
- connection: query.connectionName || 'default',
200
- type: query.type || 'query'
201
- };
202
-
203
- this.errors.push(errorRecord);
204
-
205
- // Check error rate alert
206
- const errorRate = this.getErrorRate();
207
- if (errorRate > this.options.alertThresholds.errorRate) {
208
- this.triggerAlert('error-rate', {
209
- message: `High error rate detected: ${(errorRate * 100).toFixed(2)}%`,
210
- threshold: this.options.alertThresholds.errorRate,
211
- actual: errorRate,
212
- errors: this.errors.slice(-10) // Last 10 errors
213
- });
214
- }
215
- }
216
-
217
- /**
218
- * Get slow queries from last minute
219
- * @returns {number} Number of slow queries
220
- */
221
- getSlowQueriesLastMinute() {
222
- const oneMinuteAgo = Date.now() - 60000;
223
- return this.slowQueries.filter(q =>
224
- new Date(q.timestamp).getTime() > oneMinuteAgo
225
- ).length;
226
- }
227
-
228
- /**
229
- * Get error rate
230
- * @returns {number} Error rate (0-1)
231
- */
232
- getErrorRate() {
233
- if (this.metrics.totalQueries === 0) {
234
- return 0;
235
- }
236
- return this.metrics.failedQueries / this.metrics.totalQueries;
237
- }
238
-
239
- /**
240
- * Trigger alert
241
- * @param {string} type - Alert type
242
- * @param {Object} data - Alert data
243
- */
244
- triggerAlert(type, data) {
245
- const alert = {
246
- type,
247
- timestamp: new Date().toISOString(),
248
- ...data
249
- };
250
-
251
- this.metrics.alerts.push(alert);
252
- if (this.metrics.alerts.length > 100) {
253
- this.metrics.alerts.shift();
254
- }
255
-
256
- this.emit('alert', alert);
257
- }
258
-
259
- /**
260
- * Start metrics collection
261
- */
262
- startMetricsCollection() {
263
- if (!this.options.collectMetrics) {
264
- return;
265
- }
266
-
267
- setInterval(() => {
268
- this.collectSystemMetrics();
269
- }, this.options.metricsInterval);
270
- }
271
-
272
- /**
273
- * Collect system metrics
274
- */
275
- collectSystemMetrics() {
276
- const memoryUsage = process.memoryUsage();
277
- const cpuUsage = process.cpuUsage();
278
-
279
- const systemMetrics = {
280
- timestamp: new Date().toISOString(),
281
- memory: {
282
- rss: memoryUsage.rss,
283
- heapTotal: memoryUsage.heapTotal,
284
- heapUsed: memoryUsage.heapUsed,
285
- external: memoryUsage.external,
286
- arrayBuffers: memoryUsage.arrayBuffers
287
- },
288
- cpu: {
289
- user: cpuUsage.user,
290
- system: cpuUsage.system
291
- },
292
- uptime: process.uptime(),
293
- queries: {
294
- total: this.metrics.totalQueries,
295
- successful: this.metrics.successfulQueries,
296
- failed: this.metrics.failedQueries,
297
- slow: this.metrics.slowQueries,
298
- avgTime: this.metrics.avgQueryTime,
299
- maxTime: this.metrics.maxQueryTime,
300
- minTime: this.metrics.minQueryTime === Infinity ? 0 : this.metrics.minQueryTime
301
- },
302
- connections: Object.fromEntries(this.metrics.connections)
303
- };
304
-
305
- this.emit('metrics-collected', systemMetrics);
306
- }
307
-
308
- /**
309
- * Get performance metrics
310
- * @returns {Object} Performance metrics
311
- */
312
- getMetrics() {
313
- const now = Date.now();
314
- const oneMinuteAgo = now - 60000;
315
- const fiveMinutesAgo = now - 300000;
316
- const oneHourAgo = now - 3600000;
317
-
318
- const queriesLastMinute = this.queries.filter(q =>
319
- new Date(q.timestamp).getTime() > oneMinuteAgo
320
- );
321
- const queriesLastFiveMinutes = this.queries.filter(q =>
322
- new Date(q.timestamp).getTime() > fiveMinutesAgo
323
- );
324
- const queriesLastHour = this.queries.filter(q =>
325
- new Date(q.timestamp).getTime() > oneHourAgo
326
- );
327
-
328
- const slowQueriesLastMinute = this.slowQueries.filter(q =>
329
- new Date(q.timestamp).getTime() > oneMinuteAgo
330
- );
331
-
332
- const errorsLastMinute = this.errors.filter(e =>
333
- new Date(e.timestamp).getTime() > oneMinuteAgo
334
- );
335
-
336
- return {
337
- summary: {
338
- totalQueries: this.metrics.totalQueries,
339
- successfulQueries: this.metrics.successfulQueries,
340
- failedQueries: this.metrics.failedQueries,
341
- slowQueries: this.metrics.slowQueries,
342
- errorRate: this.getErrorRate(),
343
- avgQueryTime: this.metrics.avgQueryTime,
344
- maxQueryTime: this.metrics.maxQueryTime,
345
- minQueryTime: this.metrics.minQueryTime === Infinity ? 0 : this.metrics.minQueryTime
346
- },
347
- recent: {
348
- lastMinute: {
349
- queries: queriesLastMinute.length,
350
- slowQueries: slowQueriesLastMinute.length,
351
- errors: errorsLastMinute.length,
352
- avgDuration: queriesLastMinute.length > 0
353
- ? queriesLastMinute.reduce((sum, q) => sum + q.duration, 0) / queriesLastMinute.length
354
- : 0
355
- },
356
- lastFiveMinutes: {
357
- queries: queriesLastFiveMinutes.length,
358
- avgDuration: queriesLastFiveMinutes.length > 0
359
- ? queriesLastFiveMinutes.reduce((sum, q) => sum + q.duration, 0) / queriesLastFiveMinutes.length
360
- : 0
361
- },
362
- lastHour: {
363
- queries: queriesLastHour.length,
364
- avgDuration: queriesLastHour.length > 0
365
- ? queriesLastHour.reduce((sum, q) => sum + q.duration, 0) / queriesLastHour.length
366
- : 0
367
- }
368
- },
369
- connections: Object.fromEntries(this.metrics.connections),
370
- alerts: this.metrics.alerts.slice(-10), // Last 10 alerts
371
- settings: {
372
- slowQueryThreshold: this.options.slowQueryThreshold,
373
- maxQueryHistory: this.options.maxQueryHistory,
374
- alertThresholds: this.options.alertThresholds
375
- },
376
- timestamp: new Date().toISOString()
377
- };
378
- }
379
-
380
- /**
381
- * Get slow queries
382
- * @param {number} limit - Maximum number of queries to return
383
- * @returns {Array} Slow queries
384
- */
385
- getSlowQueries(limit = 50) {
386
- return this.slowQueries.slice(-limit).reverse();
387
- }
388
-
389
- /**
390
- * Get recent errors
391
- * @param {number} limit - Maximum number of errors to return
392
- * @returns {Array} Recent errors
393
- */
394
- getRecentErrors(limit = 50) {
395
- return this.errors.slice(-limit).reverse();
396
- }
397
-
398
- /**
399
- * Get query history
400
- * @param {Object} filters - Filter options
401
- * @param {number} limit - Maximum number of queries to return
402
- * @returns {Array} Query history
403
- */
404
- getQueryHistory(filters = {}, limit = 100) {
405
- let filtered = [...this.queries];
406
-
407
- if (filters.connection) {
408
- filtered = filtered.filter(q => q.connection === filters.connection);
409
- }
410
-
411
- if (filters.type) {
412
- filtered = filtered.filter(q => q.type === filters.type);
413
- }
414
-
415
- if (filters.success !== undefined) {
416
- filtered = filtered.filter(q => q.success === filters.success);
417
- }
418
-
419
- if (filters.minDuration) {
420
- filtered = filtered.filter(q => q.duration >= filters.minDuration);
421
- }
422
-
423
- if (filters.maxDuration) {
424
- filtered = filtered.filter(q => q.duration <= filters.maxDuration);
425
- }
426
-
427
- if (filters.startTime) {
428
- const start = new Date(filters.startTime).getTime();
429
- filtered = filtered.filter(q => new Date(q.timestamp).getTime() >= start);
430
- }
431
-
432
- if (filters.endTime) {
433
- const end = new Date(filters.endTime).getTime();
434
- filtered = filtered.filter(q => new Date(q.timestamp).getTime() <= end);
435
- }
436
-
437
- return filtered.slice(-limit).reverse();
438
- }
439
-
440
- /**
441
- * Generate performance report
442
- * @returns {Object} Performance report
443
- */
444
- generateReport() {
445
- const metrics = this.getMetrics();
446
- const report = {
447
- timestamp: new Date().toISOString(),
448
- summary: metrics.summary,
449
- recommendations: [],
450
- issues: []
451
- };
452
-
453
- // Generate recommendations
454
- if (metrics.summary.errorRate > 0.05) {
455
- report.recommendations.push('High error rate detected. Consider reviewing query patterns and database connections.');
456
- }
457
-
458
- if (metrics.summary.avgQueryTime > 100) {
459
- report.recommendations.push('Average query time is high. Consider adding indexes or optimizing queries.');
460
- }
461
-
462
- if (metrics.recent.lastMinute.slowQueries > 5) {
463
- report.recommendations.push('Multiple slow queries detected in the last minute. Consider reviewing slow query logs.');
464
- }
465
-
466
- // Identify issues
467
- if (metrics.alerts.length > 0) {
468
- report.issues = metrics.alerts.map(alert => ({
469
- type: alert.type,
470
- message: alert.message,
471
- timestamp: alert.timestamp
472
- }));
473
- }
474
-
475
- // Connection analysis
476
- for (const [connection, stats] of Object.entries(metrics.connections)) {
477
- if (stats.failedQueries > 0) {
478
- report.issues.push({
479
- type: 'connection-errors',
480
- message: `Connection "${connection}" has ${stats.failedQueries} failed queries`,
481
- connection,
482
- failedQueries: stats.failedQueries
483
- });
484
- }
485
-
486
- if (stats.avgQueryTime > 500) {
487
- report.recommendations.push(`Connection "${connection}" has high average query time (${stats.avgQueryTime.toFixed(2)}ms). Consider optimizing queries or increasing connection pool size.`);
488
- }
489
- }
490
-
491
- // Memory usage analysis
492
- const memoryUsage = process.memoryUsage();
493
- const memoryUsageMB = memoryUsage.heapUsed / 1024 / 1024;
494
-
495
- if (memoryUsageMB > 500) {
496
- report.issues.push({
497
- type: 'high-memory-usage',
498
- message: `High memory usage detected: ${memoryUsageMB.toFixed(2)} MB`,
499
- memoryUsage: memoryUsageMB
500
- });
501
- report.recommendations.push('High memory usage detected. Consider implementing query result pagination or reducing cache size.');
502
- }
503
-
504
- return report;
505
- }
506
-
507
- /**
508
- * Reset performance monitor
509
- */
510
- reset() {
511
- this.queries = [];
512
- this.slowQueries = [];
513
- this.errors = [];
514
- this.metrics = {
515
- totalQueries: 0,
516
- successfulQueries: 0,
517
- failedQueries: 0,
518
- slowQueries: 0,
519
- totalQueryTime: 0,
520
- avgQueryTime: 0,
521
- maxQueryTime: 0,
522
- minQueryTime: Infinity,
523
- connections: new Map(),
524
- alerts: []
525
- };
526
- this.emit('reset');
527
- }
528
-
529
- /**
530
- * Export performance data
531
- * @param {string} format - Export format (json, csv)
532
- * @returns {string} Exported data
533
- */
534
- export(format = 'json') {
535
- const data = {
536
- queries: this.queries,
537
- slowQueries: this.slowQueries,
538
- errors: this.errors,
539
- metrics: this.getMetrics(),
540
- timestamp: new Date().toISOString()
541
- };
542
-
543
- switch (format.toLowerCase()) {
544
- case 'csv':
545
- return this.exportToCSV(data);
546
- case 'json':
547
- default:
548
- return JSON.stringify(data, null, 2);
549
- }
550
- }
551
-
552
- /**
553
- * Export to CSV
554
- * @param {Object} data - Data to export
555
- * @returns {string} CSV data
556
- */
557
- exportToCSV(data) {
558
- const csvLines = [];
559
-
560
- // Export queries
561
- if (data.queries.length > 0) {
562
- csvLines.push('=== QUERIES ===');
563
- const queryHeaders = Object.keys(data.queries[0]).join(',');
564
- csvLines.push(queryHeaders);
565
- data.queries.forEach(query => {
566
- const values = Object.values(query).map(v =>
567
- typeof v === 'string' ? `"${v.replace(/"/g, '""')}"` : v
568
- ).join(',');
569
- csvLines.push(values);
570
- });
571
- }
572
-
573
- // Export slow queries
574
- if (data.slowQueries.length > 0) {
575
- csvLines.push('\n=== SLOW QUERIES ===');
576
- const slowQueryHeaders = Object.keys(data.slowQueries[0]).join(',');
577
- csvLines.push(slowQueryHeaders);
578
- data.slowQueries.forEach(query => {
579
- const values = Object.values(query).map(v =>
580
- typeof v === 'string' ? `"${v.replace(/"/g, '""')}"` : v
581
- ).join(',');
582
- csvLines.push(values);
583
- });
584
- }
585
-
586
- // Export errors
587
- if (data.errors.length > 0) {
588
- csvLines.push('\n=== ERRORS ===');
589
- const errorHeaders = Object.keys(data.errors[0]).join(',');
590
- csvLines.push(errorHeaders);
591
- data.errors.forEach(error => {
592
- const values = Object.values(error).map(v =>
593
- typeof v === 'string' ? `"${v.replace(/"/g, '""')}"` : v
594
- ).join(',');
595
- csvLines.push(values);
596
- });
597
- }
598
-
599
- return csvLines.join('\n');
600
- }
601
-
602
- /**
603
- * Get health status
604
- * @returns {Object} Health status
605
- */
606
- getHealthStatus() {
607
- const metrics = this.getMetrics();
608
- const errorRate = metrics.summary.errorRate;
609
- const slowQueryRate = metrics.recent.lastMinute.slowQueries;
610
-
611
- let status = 'healthy';
612
- let issues = [];
613
-
614
- if (errorRate > 0.1) {
615
- status = 'critical';
616
- issues.push(`High error rate: ${(errorRate * 100).toFixed(2)}%`);
617
- } else if (errorRate > 0.05) {
618
- status = 'warning';
619
- issues.push(`Moderate error rate: ${(errorRate * 100).toFixed(2)}%`);
620
- }
621
-
622
- if (slowQueryRate > 20) {
623
- status = 'critical';
624
- issues.push(`High number of slow queries: ${slowQueryRate} in last minute`);
625
- } else if (slowQueryRate > 10) {
626
- status = 'warning';
627
- issues.push(`Moderate number of slow queries: ${slowQueryRate} in last minute`);
628
- }
629
-
630
- if (metrics.summary.avgQueryTime > 1000) {
631
- status = 'critical';
632
- issues.push(`High average query time: ${metrics.summary.avgQueryTime.toFixed(2)}ms`);
633
- } else if (metrics.summary.avgQueryTime > 500) {
634
- status = 'warning';
635
- issues.push(`Moderate average query time: ${metrics.summary.avgQueryTime.toFixed(2)}ms`);
636
- }
637
-
638
- return {
639
- status,
640
- issues,
641
- metrics: {
642
- errorRate,
643
- slowQueryRate,
644
- avgQueryTime: metrics.summary.avgQueryTime,
645
- totalQueries: metrics.summary.totalQueries,
646
- timestamp: new Date().toISOString()
647
- }
648
- };
649
- }
650
- }
651
-
652
- export default PerformanceMonitor;