- Add ResourceMonitor for tracking system resource usage (memory, CPU, network) - Implement API request tracking with performance metrics and error monitoring - Create usePerformanceMonitor hook for component-level performance tracking - Add useAsyncPerformanceTracker for async operation monitoring - Track memory warnings, performance bottlenecks, and network failures - Support configurable thresholds for resource usage alerts - Implement periodic sampling with intelligent reporting These utilities enable proactive performance monitoring to identify and address bottlenecks before they impact user experience.
116 lines
3.5 KiB
TypeScript
116 lines
3.5 KiB
TypeScript
import { api as originalApi } from './api';
|
|
import { analytics, eventBuilders } from './analytics';
|
|
|
|
// Performance thresholds (in milliseconds)
|
|
const PERFORMANCE_THRESHOLDS = {
|
|
fast: 100,
|
|
normal: 500,
|
|
slow: 2000,
|
|
bottleneck: 5000,
|
|
};
|
|
|
|
// Memory threshold (in MB)
|
|
const MEMORY_WARNING_THRESHOLD = 100;
|
|
|
|
/**
|
|
* Wraps an API method with error and performance tracking
|
|
*/
|
|
function wrapApiMethod<T extends (...args: any[]) => Promise<any>>(
|
|
methodName: string,
|
|
method: T
|
|
): T {
|
|
return (async (...args: any[]) => {
|
|
const startTime = performance.now();
|
|
const startMemory = ('memory' in performance ? (performance as any).memory?.usedJSHeapSize : 0) || 0;
|
|
let retryCount = 0;
|
|
|
|
const trackPerformance = (success: boolean, error?: any) => {
|
|
const duration = performance.now() - startTime;
|
|
const memoryUsed = ((('memory' in performance ? (performance as any).memory?.usedJSHeapSize : 0) || 0) - startMemory) / (1024 * 1024); // Convert to MB
|
|
|
|
// Track API errors
|
|
if (!success && error) {
|
|
const event = eventBuilders.apiError({
|
|
endpoint: methodName,
|
|
error_code: error.code || error.status || 'unknown',
|
|
retry_count: retryCount,
|
|
response_time_ms: duration,
|
|
});
|
|
analytics.track(event.event, event.properties);
|
|
}
|
|
|
|
// Track performance bottlenecks
|
|
if (duration > PERFORMANCE_THRESHOLDS.bottleneck) {
|
|
const event = eventBuilders.performanceBottleneck({
|
|
operation_type: `api.${methodName}`,
|
|
duration_ms: duration,
|
|
data_size: undefined, // Could be enhanced to track payload size
|
|
threshold_exceeded: true,
|
|
});
|
|
analytics.track(event.event, event.properties);
|
|
}
|
|
|
|
// Track network performance
|
|
const connectionQuality =
|
|
duration < PERFORMANCE_THRESHOLDS.fast ? 'excellent' :
|
|
duration < PERFORMANCE_THRESHOLDS.normal ? 'good' : 'poor';
|
|
|
|
if (success) {
|
|
const networkEvent = eventBuilders.networkPerformance({
|
|
endpoint_type: 'api',
|
|
latency_ms: duration,
|
|
payload_size_bytes: 0, // Could be enhanced with actual payload size
|
|
connection_quality: connectionQuality,
|
|
retry_count: retryCount,
|
|
circuit_breaker_triggered: false,
|
|
});
|
|
analytics.track(networkEvent.event, networkEvent.properties);
|
|
}
|
|
|
|
// Track memory warnings
|
|
if (memoryUsed > MEMORY_WARNING_THRESHOLD) {
|
|
const event = eventBuilders.memoryWarning({
|
|
component: `api.${methodName}`,
|
|
memory_mb: memoryUsed,
|
|
threshold_exceeded: true,
|
|
gc_count: undefined, // Could be enhanced with GC tracking
|
|
});
|
|
analytics.track(event.event, event.properties);
|
|
}
|
|
};
|
|
|
|
try {
|
|
const result = await method(...args);
|
|
trackPerformance(true);
|
|
return result;
|
|
} catch (error) {
|
|
trackPerformance(false, error);
|
|
throw error;
|
|
}
|
|
}) as T;
|
|
}
|
|
|
|
/**
|
|
* Creates a tracked version of the API object
|
|
*/
|
|
function createTrackedApi() {
|
|
const trackedApi: any = {};
|
|
|
|
// Wrap each method in the original API
|
|
for (const [key, value] of Object.entries(originalApi)) {
|
|
if (typeof value === 'function') {
|
|
trackedApi[key] = wrapApiMethod(key, value);
|
|
} else {
|
|
trackedApi[key] = value;
|
|
}
|
|
}
|
|
|
|
return trackedApi as typeof originalApi;
|
|
}
|
|
|
|
// Export the tracked API
|
|
export const api = createTrackedApi();
|
|
|
|
// Re-export types from the original API module
|
|
export * from './api';
|