UNPKG

@crudmates/profiler

Version:

A comprehensive performance profiling utility for Node.js applications with timing, memory monitoring, and garbage collection tracking. Perfect for debugging performance issues, memory leaks, and optimizing application performance.

427 lines 11.8 kB
/** * Logger interface for profiling output */ export interface Logger { debug?: (message: string | object, ...args: unknown[]) => void; log?: (message: string | object, ...args: unknown[]) => void; warn?: (message: string | object, ...args: unknown[]) => void; error?: (message: string | object, ...args: unknown[]) => void; verbose?: (message: string | object, ...args: unknown[]) => void; [key: string]: ((message: string | object, ...args: unknown[]) => void) | undefined; } /** * Performance profiling utility options */ export interface ProfileConfig { /** Enable memory profiling */ trackMemory?: boolean; /** Enable garbage collection monitoring */ enableGC?: boolean; /** Memory threshold in MB to trigger GC */ gcThresholdMB?: number; /** Logger instance to use (defaults to console) */ logger?: Logger | Console; /** Custom tags to include in logs */ tags?: Record<string, unknown>; /** Log level for profiling output */ logLevel?: 'debug' | 'log' | 'verbose'; /** Whether to log individual checkpoints (default: true) */ logSteps?: boolean; /** Enable verbose logging with detailed intermediate steps (default: false) */ verbose?: boolean; /** Whether to log any output at all (default: true) */ silent?: boolean; } /** * Performance profiling result */ export interface ProfileResult { /** Function name or identifier */ name: string; /** Execution duration in milliseconds */ duration: number; /** Memory usage before execution */ memBefore?: NodeJS.MemoryUsage; /** Memory usage after execution */ memAfter?: NodeJS.MemoryUsage; /** Memory delta (difference) */ memDelta?: { heapUsed: number; heapTotal: number; external: number; rss: number; }; /** Whether GC was triggered */ gcTriggered?: boolean; /** Custom tags */ tags?: Record<string, unknown>; /** Result of the profiled function */ result?: unknown; /** Error if function threw */ error?: unknown; } /** * Profile a function execution with timing and memory monitoring * * @example * ```typescript * // As a wrapper function * const result = await profile( * () => someAsyncOperation(), * 'MyOperation', * { trackMemory: true, enableGC: true } * ); * * // Using with CarService method * const { result: cars } = await profile( * () => this.carRepository.find({ where: { marketplaceVisible: true } }), * 'fetchMarketplaceCars', * { * trackMemory: true, * enableGC: true, * gcThresholdMB: 100, * logger: this.logger, * tags: { operation: 'database-query' } * } * ); * ``` */ export declare function profile<T>(fn: () => T | Promise<T>, name: string, config?: ProfileConfig): Promise<{ result: T; profile: ProfileResult; }>; /** * Decorator for profiling class methods * * @example * ```typescript * class CarService { * @Profile('listCars', { trackMemory: true, enableGC: true }) * async listCar(data: AdminListCarRequestPayload.AsObject) { * // method implementation * } * * @Profile('searchCars', { * trackMemory: true, * gcThresholdMB: 150, * tags: { operation: 'search' } * }) * async searchCar(data: MarketplaceSearchRequestPayload.AsObject) { * // method implementation * } * } * ``` */ export declare function Profile(name?: string, config?: ProfileConfig): <T extends (...args: any[]) => any>(target: T, context: { name: string | symbol; }) => T; /** * Simple timing utility for quick performance checks * * @example * ```typescript * // Basic usage * const timer = new Timer('database-query'); * const cars = await this.carRepository.find(); * timer.stop({ carCount: cars.length }); * * // Static method usage * const result = await Timer.time( * () => this.processLargeBatch(data), * 'processLargeBatch' * ); * ``` */ export declare class Timer { private startTime; private name; private logger; constructor(name: string, logger?: Logger | Console); stop(data?: Record<string, unknown>): number; static time<T>(fn: () => T | Promise<T>, name: string, logger?: Logger | Console): Promise<T>; } /** * Memory monitoring utility for tracking memory usage over time * * @example * ```typescript * const monitor = new MemMonitor(this.logger); * * monitor.snap('start'); * await this.processAlerts(alerts); * monitor.snap('after-processing'); * * // Compare memory usage * monitor.compare('start', 'after-processing'); * * // Get all snapshots for analysis * const snapshots = monitor.getSnaps(); * ``` */ export declare class MemMonitor { private snaps; private logger; constructor(logger?: Logger | Console); snap(label?: string): NodeJS.MemoryUsage; compare(fromLabel?: string, toLabel?: string): void; clear(): void; getSnaps(): Array<{ timestamp: number; usage: NodeJS.MemoryUsage; label?: string; }>; } /** * Advanced profiler for continuous monitoring * Useful for monitoring memory-intensive operations like alert processing * * @example * ```typescript * const profiler = new Profiler('alert-processing', { * enableGC: true, * gcThresholdMB: 100, * logger: this.logger * }); * * profiler.start(); * * for (const alert of alerts) { * profiler.mark(`processing-alert-${alert.id}`); * await this.processAlert(alert); * } * * const summary = profiler.end(); * // Returns detailed performance summary * ``` */ export declare class Profiler { private name; private config; private startTime; private marks; private gcCount; constructor(name: string, config?: ProfileConfig); start(): void; mark(label: string): void; /** * Get current performance summary without ending the profiler */ getSummary(): { name: string; elapsed: number; markCount: number; gcCount: number; lastStep?: string; lastStepDuration?: number; }; /** * Get detailed phase breakdown up to current point */ getSteps(): Array<{ step: string; duration: number; durationFormatted: string; percentage: number; }>; end(): { name: string; totalDuration: number; totalGCCount: number; marks: Array<{ label: string; timestamp: number; timestampFormatted: string; stepDuration?: number; stepDurationFormatted?: string; memory?: { heap: string; rss: string; }; gcTriggered?: boolean; }>; memDeltas?: Array<{ from: string; to: string; duration: string; heapDelta: string; rssDelta: string; }>; steps?: Array<{ step: string; duration: number; durationFormatted: string; startTime: number; endTime: number; gcTriggered?: boolean; }>; }; private log; } /** * Utility function to monitor memory leaks * Useful for detecting memory growth patterns */ export declare function detectMemLeak(measurements: NodeJS.MemoryUsage[], threshold?: number): { isLeaking: boolean; trend: 'increasing' | 'decreasing' | 'stable'; avgGrowth: number; }; /** * V8 profiling options configuration */ export interface V8Options { /** Required memory budget in MB for V8 profiling data */ maxMemoryBudgetMB: number; /** Interval in minutes for automatic logging and data clearing (default: 60) */ intervalMinutes?: number; /** Process V8 data incrementally vs accumulating (default: true) */ streamingMode?: boolean; /** Enable CPU profiling for performance bottleneck analysis (default: true) */ cpuProfiling?: boolean; /** Enable sampling heap profiler for memory allocation tracking (default: true) */ samplingHeapProfiler?: boolean; /** Logger instance to use (defaults to console) */ logger?: Logger | Console; /** Suppress configuration warnings (default: false) */ suppressWarnings?: boolean; } /** * V8 profiling insights result */ export interface V8Insights { /** Duration of the profiling session */ duration: number; /** Top CPU-consuming functions */ topFunctions: Array<{ functionName: string; selfTime: number; totalTime: number; percentage: number; }>; /** Memory allocation hot spots */ memoryHotspots: Array<{ allocation: string; size: number; count: number; }>; /** Garbage collection impact metrics */ gcImpact: { gcTime: number; gcCount: number; avgGcDuration: number; }; /** Memory usage at interval end */ memoryUsage: { heap: string; rss: string; external: string; }; } /** * Advanced V8 profiler for long-running application analysis * Provides CPU profiling and memory allocation tracking with automatic * interval-based logging to prevent memory buildup * * @example * ```typescript * // Start continuous profiling with 60-minute intervals * const v8Profiler = new V8Profiler('production-app', { * maxMemoryBudgetMB: 100, * intervalMinutes: 60, * cpuProfiling: true, * samplingHeapProfiler: true * }); * * await v8Profiler.startContinuousProfiling(); * // Runs indefinitely, auto-logs insights every 60 minutes * * // Later, stop profiling * await v8Profiler.stopContinuousProfiling(); * ``` */ export declare class V8Profiler { private options; private session; private intervalTimer?; private currentMemoryUsage; private profilingStartTime; private isRunning; constructor(_name: string, options: V8Options); /** * Initialize V8 Inspector session */ private initializeInspector; /** * Validate configuration and show warnings if needed */ private validateConfiguration; /** * Calculate estimated memory usage per minute */ private calculateEstimatedUsage; /** * Log warning message if warnings are not suppressed */ private warn; /** * Log info message */ private log; /** * Start continuous V8 profiling with automatic interval logging */ startContinuousProfiling(): Promise<void>; /** * Stop continuous V8 profiling */ stopContinuousProfiling(): Promise<V8Insights>; /** * Manually flush current interval (useful for testing) */ flushCurrentInterval(): Promise<V8Insights>; /** * Check if memory budget is exceeded */ isMemoryBudgetExceeded(): boolean; /** * Get current memory usage by V8 profiler */ getCurrentMemoryUsage(): number; /** * Start V8 profiling session */ private startProfilingSession; /** * Stop V8 profiling session */ private stopProfilingSession; /** * Reset profiling session (for interval flushing) */ private resetProfilingSession; /** * Setup interval timer for automatic flushing */ private setupIntervalTimer; /** * Collect and process V8 insights */ private collectInsights; /** * Collect CPU profiling insights */ private collectCPUProfile; /** * Collect heap profiling insights */ private collectHeapProfile; /** * Collect current memory usage */ private collectMemoryUsage; /** * Estimate memory size of profile data */ private estimateProfileSize; } //# sourceMappingURL=index.d.ts.map