| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- // GrabZilla 2.1 - Performance Monitoring
- // Tracks CPU, memory, download, and conversion metrics
- const os = require('os');
- /**
- * Performance monitoring system for tracking system resources and download statistics
- */
- class PerformanceMonitor {
- constructor() {
- this.metrics = {
- downloads: [],
- conversions: [],
- cpuSamples: [],
- memorySamples: []
- };
- this.startTime = Date.now();
- this.monitorInterval = null;
- this.startMonitoring();
- }
- /**
- * Start monitoring system metrics every 2 seconds
- */
- startMonitoring() {
- this.monitorInterval = setInterval(() => {
- this.sampleSystemMetrics();
- }, 2000); // Every 2 seconds
- }
- /**
- * Sample current CPU and memory usage
- */
- sampleSystemMetrics() {
- // Calculate CPU usage
- const cpus = os.cpus();
- const totalIdle = cpus.reduce((acc, cpu) => acc + cpu.times.idle, 0);
- const totalTick = cpus.reduce((acc, cpu) => {
- return acc + Object.values(cpu.times).reduce((a, b) => a + b, 0);
- }, 0);
- const cpuUsage = 100 - (100 * totalIdle / totalTick);
- this.metrics.cpuSamples.push({
- timestamp: Date.now(),
- usage: cpuUsage,
- cores: cpus.length
- });
- // Memory usage
- const memUsage = process.memoryUsage();
- this.metrics.memorySamples.push({
- timestamp: Date.now(),
- heapUsed: memUsage.heapUsed,
- heapTotal: memUsage.heapTotal
- });
- // Keep only last 100 samples (~ 3 minutes of history)
- if (this.metrics.cpuSamples.length > 100) {
- this.metrics.cpuSamples.shift();
- this.metrics.memorySamples.shift();
- }
- }
- /**
- * Record a completed download
- * @param {Object} downloadData - Download information
- * @param {string} downloadData.videoId - Video ID
- * @param {number} downloadData.duration - Download duration in ms
- * @param {string} downloadData.status - Download status
- */
- recordDownload(downloadData) {
- this.metrics.downloads.push({
- videoId: downloadData.videoId,
- duration: downloadData.duration,
- success: downloadData.status === 'completed',
- timestamp: Date.now()
- });
- // Keep only last 1000 download records
- if (this.metrics.downloads.length > 1000) {
- this.metrics.downloads.shift();
- }
- }
- /**
- * Record a completed conversion
- * @param {Object} conversionData - Conversion information
- * @param {string} conversionData.videoId - Video ID
- * @param {number} conversionData.duration - Conversion duration in ms
- * @param {boolean} conversionData.usedGPU - Whether GPU was used
- */
- recordConversion(conversionData) {
- this.metrics.conversions.push({
- videoId: conversionData.videoId,
- duration: conversionData.duration,
- usedGPU: conversionData.usedGPU,
- timestamp: Date.now()
- });
- // Keep only last 1000 conversion records
- if (this.metrics.conversions.length > 1000) {
- this.metrics.conversions.shift();
- }
- }
- /**
- * Get current statistics
- * @returns {Object} Performance statistics
- */
- getStats() {
- return {
- downloads: {
- total: this.metrics.downloads.length,
- successful: this.metrics.downloads.filter(d => d.success).length,
- failed: this.metrics.downloads.filter(d => !d.success).length
- },
- conversions: {
- total: this.metrics.conversions.length,
- gpu: this.metrics.conversions.filter(c => c.usedGPU).length,
- cpu: this.metrics.conversions.filter(c => !c.usedGPU).length
- },
- system: {
- currentCPU: this.getCurrentCPU(),
- currentMemory: this.getCurrentMemory(),
- uptime: Date.now() - this.startTime
- }
- };
- }
- /**
- * Get current CPU usage percentage
- * @returns {string} CPU usage as formatted string
- */
- getCurrentCPU() {
- const latest = this.metrics.cpuSamples[this.metrics.cpuSamples.length - 1];
- return latest ? latest.usage.toFixed(1) : '0.0';
- }
- /**
- * Get current memory usage
- * @returns {Object} Memory usage in MB
- */
- getCurrentMemory() {
- const latest = this.metrics.memorySamples[this.metrics.memorySamples.length - 1];
- if (!latest) return { used: '0.0', total: '0.0' };
- return {
- used: (latest.heapUsed / 1024 / 1024).toFixed(1),
- total: (latest.heapTotal / 1024 / 1024).toFixed(1)
- };
- }
- /**
- * Get average CPU usage over recent samples
- * @param {number} samples - Number of recent samples to average (default 10)
- * @returns {number} Average CPU usage
- */
- getAverageCPU(samples = 10) {
- const recentSamples = this.metrics.cpuSamples.slice(-samples);
- if (recentSamples.length === 0) return 0;
- const sum = recentSamples.reduce((acc, sample) => acc + sample.usage, 0);
- return sum / recentSamples.length;
- }
- /**
- * Reset all metrics
- */
- reset() {
- this.metrics = {
- downloads: [],
- conversions: [],
- cpuSamples: [],
- memorySamples: []
- };
- this.startTime = Date.now();
- }
- /**
- * Stop monitoring and clean up resources
- */
- stop() {
- if (this.monitorInterval) {
- clearInterval(this.monitorInterval);
- this.monitorInterval = null;
- }
- }
- }
- module.exports = PerformanceMonitor;
|