jerkjs 2.5.6 → 2.6.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/CHANGELOG.md +167 -79
- package/README.md +134 -146
- package/RESULTADOS_WAF.md +63 -0
- package/doc-2.5/ADMIN_EXTENSION_COMMANDS_MANUAL.md +261 -0
- package/doc-2.5/ADMIN_EXTENSION_HOOK_EXAMPLE.md +28 -0
- package/doc-2.5/ADMIN_EXTENSION_INTEGRATION_MANUAL.md +232 -0
- package/doc-2.5/CACHE_SYSTEM_MAP.md +206 -0
- package/doc-2.5/MANUAL_MODULOS_ADMIN.md +287 -0
- package/doc-2.5/QUEUE_CLI_MODULE_MANUAL.md +289 -0
- package/doc-2.5/QUEUE_SYSTEM_MANUAL.md +320 -0
- package/doc-2.5/ROUTE_CACHE_MODULE_MANUAL.md +205 -0
- package/doc-2.5/WAF_MODULE_MANUAL.md +229 -0
- package/index.js +19 -4
- package/jerk-admin-client/README.md +69 -0
- package/jerk-admin-client/package.json +23 -0
- package/jerk-admin-client.js +257 -0
- package/lib/admin/AdminExtension.js +491 -0
- package/lib/admin/ModuleLoader.js +77 -0
- package/lib/admin/config.js +21 -0
- package/lib/admin/modules/CacheModule.js +145 -0
- package/lib/admin/modules/ControllerGeneratorModule.js +414 -0
- package/lib/admin/modules/QueueManagementModule.js +265 -0
- package/lib/admin/modules/RouteCacheModule.js +227 -0
- package/lib/admin/modules/RouteManagerModule.js +468 -0
- package/lib/admin/modules/STATS_MODULE_README.md +113 -0
- package/lib/admin/modules/StatsModule.js +140 -0
- package/lib/admin/modules/SystemModule.js +140 -0
- package/lib/admin/modules/TimeModule.js +95 -0
- package/lib/admin/modules/ViewCacheStatsModule.js +92 -0
- package/lib/admin/modules/WAFModule.js +737 -0
- package/lib/cache/CacheHooks.js +141 -0
- package/lib/core/server.js +223 -77
- package/lib/middleware/firewall.js +112 -17
- package/lib/mvc/viewEngine.js +89 -5
- package/lib/queue/GlobalQueueStorage.js +38 -0
- package/lib/queue/QueueSystem.js +451 -0
- package/lib/queue/admin_example.js +114 -0
- package/lib/queue/example.js +268 -0
- package/lib/queue/integration.js +109 -0
- package/lib/router/RouteMatcher.js +242 -54
- package/lib/utils/globalStats.js +16 -0
- package/lib/utils/globalViewCacheInfo.js +16 -0
- package/lib/utils/globalWAFStats.js +54 -0
- package/package.json +2 -2
- package/test-colors.js +46 -0
- package/test-help-alias.js +31 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Módulo de Estadísticas para la Extensión de Administración de JERK Framework
|
|
3
|
+
* Módulo personalizado para mostrar estadísticas del servidor
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class StatsModule {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor del módulo de estadísticas
|
|
9
|
+
* @param {Object} adminExtension - Instancia de la extensión de administración
|
|
10
|
+
*/
|
|
11
|
+
constructor(adminExtension) {
|
|
12
|
+
this.adminExtension = adminExtension;
|
|
13
|
+
this.name = 'Statistics Module';
|
|
14
|
+
this.description = 'Módulo para mostrar estadísticas del servidor';
|
|
15
|
+
this.commands = ['stats', 'statistics', 'requests', 'endpoints'];
|
|
16
|
+
|
|
17
|
+
// Cargar el objeto global de estadísticas
|
|
18
|
+
this.globalStats = require('../../utils/globalStats').globalStats;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Manejador para los comandos del módulo de estadísticas
|
|
23
|
+
* @param {string} command - Comando a ejecutar
|
|
24
|
+
* @param {Object} socket - Socket de la conexión
|
|
25
|
+
*/
|
|
26
|
+
handleCommand(command, socket) {
|
|
27
|
+
switch (command) {
|
|
28
|
+
case 'stats':
|
|
29
|
+
case 'statistics':
|
|
30
|
+
this.showGeneralStats(socket);
|
|
31
|
+
break;
|
|
32
|
+
case 'requests':
|
|
33
|
+
this.showRequestStats(socket);
|
|
34
|
+
break;
|
|
35
|
+
case 'endpoints':
|
|
36
|
+
this.showEndpointStats(socket);
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
socket.write(`Comando desconocido para el módulo de estadísticas: ${command}\n`);
|
|
40
|
+
socket.write(`Comandos disponibles: stats, statistics, requests, endpoints\n\n`);
|
|
41
|
+
socket.write(`> `);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Muestra estadísticas generales
|
|
47
|
+
* @param {Object} socket - Socket de la conexión
|
|
48
|
+
*/
|
|
49
|
+
showGeneralStats(socket) {
|
|
50
|
+
const formattedRequestBytes = this.formatBytes(this.globalStats.requestBytes);
|
|
51
|
+
const formattedResponseBytes = this.formatBytes(this.globalStats.responseBytes);
|
|
52
|
+
|
|
53
|
+
socket.write('\n=== Estadísticas Generales ===\n');
|
|
54
|
+
socket.write(`Solicitudes procesadas: ${this.globalStats.requestsProcessed}\n`);
|
|
55
|
+
socket.write(`Solicitudes procesadas (KB): ${formattedRequestBytes}\n`);
|
|
56
|
+
socket.write(`Respuestas enviadas: ${this.globalStats.responsesSent}\n`);
|
|
57
|
+
socket.write(`Respuestas enviadas (KB): ${formattedResponseBytes}\n`);
|
|
58
|
+
socket.write(`Rutas registradas: ${this.adminExtension.registeredRoutes.length}\n`);
|
|
59
|
+
socket.write(`Rutas activas: ${this.adminExtension.activeRoutes.size}\n\n`);
|
|
60
|
+
socket.write(`> `);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Muestra estadísticas de solicitudes
|
|
65
|
+
* @param {Object} socket - Socket de la conexión
|
|
66
|
+
*/
|
|
67
|
+
showRequestStats(socket) {
|
|
68
|
+
socket.write('\n=== Estadísticas de Solicitudes ===\n');
|
|
69
|
+
socket.write(`Total de solicitudes procesadas: ${this.globalStats.requestsProcessed}\n`);
|
|
70
|
+
socket.write(`Total de bytes recibidos: ${this.formatBytes(this.globalStats.requestBytes)}\n`);
|
|
71
|
+
|
|
72
|
+
// Mostrar accesos a rutas
|
|
73
|
+
if (this.globalStats.routeAccesses.size > 0) {
|
|
74
|
+
socket.write('\nAccesos a rutas (Input/Output):\n');
|
|
75
|
+
for (const [route, count] of this.globalStats.routeAccesses) {
|
|
76
|
+
socket.write(` ${route}: ${count} accesos\n`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
socket.write('\n> ');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Muestra estadísticas de endpoints
|
|
85
|
+
* @param {Object} socket - Socket de la conexión
|
|
86
|
+
*/
|
|
87
|
+
showEndpointStats(socket) {
|
|
88
|
+
socket.write('\n=== Estadísticas de Endpoints y Rutas ===\n');
|
|
89
|
+
|
|
90
|
+
// Mostrar endpoints más accedidos
|
|
91
|
+
if (this.globalStats.endpointHits.size > 0) {
|
|
92
|
+
socket.write('Endpoints más accedidos:\n');
|
|
93
|
+
|
|
94
|
+
// Convertir el mapa a array y ordenar por número de hits
|
|
95
|
+
const sortedEndpoints = Array.from(this.globalStats.endpointHits.entries())
|
|
96
|
+
.sort((a, b) => b[1] - a[1])
|
|
97
|
+
.slice(0, 10); // Mostrar top 10
|
|
98
|
+
|
|
99
|
+
for (const [endpoint, hits] of sortedEndpoints) {
|
|
100
|
+
socket.write(` ${endpoint}: ${hits} hits\n`);
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
socket.write('No hay datos de endpoints accedidos.\n');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Mostrar rutas más accedidas
|
|
107
|
+
if (this.globalStats.routeAccesses.size > 0) {
|
|
108
|
+
socket.write('\nRutas más accedidas:\n');
|
|
109
|
+
|
|
110
|
+
// Convertir el mapa a array y ordenar por número de accesos
|
|
111
|
+
const sortedRoutes = Array.from(this.globalStats.routeAccesses.entries())
|
|
112
|
+
.sort((a, b) => b[1] - a[1])
|
|
113
|
+
.slice(0, 10); // Mostrar top 10
|
|
114
|
+
|
|
115
|
+
for (const [route, accesses] of sortedRoutes) {
|
|
116
|
+
socket.write(` ${route}: ${accesses} accesos\n`);
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
socket.write('\nNo hay datos de rutas accedidas.\n');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
socket.write('\n> ');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Formatea bytes a una unidad legible
|
|
127
|
+
* @param {number} bytes - Cantidad en bytes
|
|
128
|
+
* @returns {string} - Cantidad formateada con unidad
|
|
129
|
+
*/
|
|
130
|
+
formatBytes(bytes) {
|
|
131
|
+
// Manejar valores nulos o indefinidos
|
|
132
|
+
if (bytes == null || isNaN(bytes) || bytes === 0) return '0 Bytes';
|
|
133
|
+
const k = 1024;
|
|
134
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
135
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
136
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = StatsModule;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Módulo de Sistema para la Extensión de Administración de JERK Framework
|
|
3
|
+
* Módulo personalizado para mostrar información del sistema
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class SystemModule {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor del módulo de sistema
|
|
9
|
+
* @param {Object} adminExtension - Instancia de la extensión de administración
|
|
10
|
+
*/
|
|
11
|
+
constructor(adminExtension) {
|
|
12
|
+
this.adminExtension = adminExtension;
|
|
13
|
+
this.name = 'System Info Module';
|
|
14
|
+
this.description = 'Módulo para mostrar información del sistema';
|
|
15
|
+
this.commands = ['sysinfo', 'system', 'resources'];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Manejador para los comandos del módulo de sistema
|
|
20
|
+
* @param {string} command - Comando a ejecutar
|
|
21
|
+
* @param {Object} socket - Socket de la conexión
|
|
22
|
+
*/
|
|
23
|
+
handleCommand(command, socket) {
|
|
24
|
+
switch (command) {
|
|
25
|
+
case 'sysinfo':
|
|
26
|
+
case 'system':
|
|
27
|
+
case 'resources':
|
|
28
|
+
this.showSystemInfo(socket);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
socket.write(`Comando desconocido para el módulo de sistema: ${command}\n`);
|
|
32
|
+
socket.write(`Comandos disponibles: sysinfo, system, resources\n\n`);
|
|
33
|
+
socket.write(`> `);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Muestra información del sistema en formato de tabla con color verde
|
|
39
|
+
* @param {Object} socket - Socket de la conexión
|
|
40
|
+
*/
|
|
41
|
+
showSystemInfo(socket) {
|
|
42
|
+
const os = require('os');
|
|
43
|
+
const memUsage = process.memoryUsage();
|
|
44
|
+
const cpuInfo = os.cpus();
|
|
45
|
+
const totalMem = os.totalmem();
|
|
46
|
+
const freeMem = os.freemem();
|
|
47
|
+
const usedMem = totalMem - freeMem;
|
|
48
|
+
const uptime = process.uptime();
|
|
49
|
+
|
|
50
|
+
// Obtener información del proceso
|
|
51
|
+
const pid = process.pid;
|
|
52
|
+
const ppid = process.ppid;
|
|
53
|
+
const execPath = process.execPath;
|
|
54
|
+
const version = process.version;
|
|
55
|
+
|
|
56
|
+
// Calcular uso de CPU (aproximado)
|
|
57
|
+
let totalIdle = 0, totalTick = 0;
|
|
58
|
+
for (const cpu of cpuInfo) {
|
|
59
|
+
for (const type in cpu.times) {
|
|
60
|
+
totalTick += cpu.times[type];
|
|
61
|
+
}
|
|
62
|
+
totalIdle += cpu.times.idle;
|
|
63
|
+
}
|
|
64
|
+
const avgTick = totalTick / cpuInfo.length;
|
|
65
|
+
const avgIdle = totalIdle / cpuInfo.length;
|
|
66
|
+
const cpuUsage = Math.round((1 - avgIdle / avgTick) * 10000) / 100;
|
|
67
|
+
|
|
68
|
+
// Formatear la información en una tabla
|
|
69
|
+
const table = `
|
|
70
|
+
\x1b[32m
|
|
71
|
+
╔════════════════════════════════════════════════════════════════╗
|
|
72
|
+
║ INFORMACIÓN DEL SISTEMA ║
|
|
73
|
+
╠════════════════════════════════════════════════════════════════╣
|
|
74
|
+
║ Recursos del Sistema ║
|
|
75
|
+
╠────────────────────────────────────────────────────────────────╣
|
|
76
|
+
║ Memoria Total: ${this.padRight(this.formatBytes(totalMem), 15)} ║ Memoria Libre: ${this.padRight(this.formatBytes(freeMem), 15)} ║
|
|
77
|
+
║ Memoria Usada: ${this.padRight(this.formatBytes(usedMem), 15)} ║ Uso de CPU: ${this.padRight(cpuUsage + '%', 15)} ║
|
|
78
|
+
║ Procesos CPU: ${this.padRight(cpuInfo.length + '', 15)} ║ Uptime Proceso: ${this.padRight(this.formatUptime(uptime), 15)} ║
|
|
79
|
+
╠════════════════════════════════════════════════════════════════╣
|
|
80
|
+
║ Información del Proceso ║
|
|
81
|
+
╠────────────────────────────────────────────────────────────────╣
|
|
82
|
+
║ PID: ${this.padRight(pid + '', 15)} ║ PPID: ${this.padRight(ppid + '', 15)} ║
|
|
83
|
+
║ Versión Node: ${this.padRight(version, 15)} ║ Ruta Ejecutable: ${this.padRight(execPath.split('/').pop().substring(0, 15), 15)} ║
|
|
84
|
+
╠════════════════════════════════════════════════════════════════╣
|
|
85
|
+
║ Uso de Memoria del Proceso ║
|
|
86
|
+
╠────────────────────────────────────────────────────────────────╣
|
|
87
|
+
║ RSS: ${this.padRight(this.formatBytes(memUsage.rss), 15)} ║ Heap Total: ${this.padRight(this.formatBytes(memUsage.heapTotal), 15)} ║
|
|
88
|
+
║ Heap Usado: ${this.padRight(this.formatBytes(memUsage.heapUsed), 15)} ║ External: ${this.padRight(this.formatBytes(memUsage.external), 15)} ║
|
|
89
|
+
╚════════════════════════════════════════════════════════════════╝\x1b[0m`;
|
|
90
|
+
|
|
91
|
+
socket.write(table + '\n\n');
|
|
92
|
+
socket.write(`> `);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Formatea bytes a una unidad legible
|
|
97
|
+
* @param {number} bytes - Cantidad en bytes
|
|
98
|
+
* @returns {string} - Cantidad formateada con unidad
|
|
99
|
+
*/
|
|
100
|
+
formatBytes(bytes) {
|
|
101
|
+
if (bytes === 0) return '0 Bytes';
|
|
102
|
+
const k = 1024;
|
|
103
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
104
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
105
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Formatea el uptime en una cadena legible
|
|
110
|
+
* @param {number} seconds - Segundos de uptime
|
|
111
|
+
* @returns {string} - Uptime formateado
|
|
112
|
+
*/
|
|
113
|
+
formatUptime(seconds) {
|
|
114
|
+
const days = Math.floor(seconds / (3600 * 24));
|
|
115
|
+
const hours = Math.floor((seconds % (3600 * 24)) / 3600);
|
|
116
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
117
|
+
const secs = Math.floor(seconds % 60);
|
|
118
|
+
|
|
119
|
+
let result = '';
|
|
120
|
+
if (days > 0) result += `${days}d `;
|
|
121
|
+
if (hours > 0) result += `${hours}h `;
|
|
122
|
+
if (minutes > 0) result += `${minutes}m `;
|
|
123
|
+
result += `${secs}s`;
|
|
124
|
+
|
|
125
|
+
return result.trim();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Ajusta texto a la derecha con padding
|
|
130
|
+
* @param {string} str - Texto a ajustar
|
|
131
|
+
* @param {number} length - Longitud total
|
|
132
|
+
* @returns {string} - Texto ajustado
|
|
133
|
+
*/
|
|
134
|
+
padRight(str, length) {
|
|
135
|
+
str = str + '';
|
|
136
|
+
return str.length < length ? str + ' '.repeat(length - str.length) : str.substring(0, length);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = SystemModule;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Módulo de Tiempo para la Extensión de Administración de JERK Framework
|
|
3
|
+
* Módulo personalizado para mostrar hora y fecha
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class TimeModule {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor del módulo de tiempo
|
|
9
|
+
* @param {Object} adminExtension - Instancia de la extensión de administración
|
|
10
|
+
*/
|
|
11
|
+
constructor(adminExtension) {
|
|
12
|
+
this.adminExtension = adminExtension;
|
|
13
|
+
this.name = 'Time Module';
|
|
14
|
+
this.description = 'Módulo para mostrar hora y fecha';
|
|
15
|
+
this.commands = ['time', 'date'];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Manejador para los comandos del módulo de tiempo
|
|
20
|
+
* @param {string} command - Comando a ejecutar
|
|
21
|
+
* @param {Object} socket - Socket de la conexión
|
|
22
|
+
*/
|
|
23
|
+
handleCommand(command, socket) {
|
|
24
|
+
switch (command) {
|
|
25
|
+
case 'time':
|
|
26
|
+
this.showTime(socket);
|
|
27
|
+
break;
|
|
28
|
+
case 'date':
|
|
29
|
+
this.showDate(socket);
|
|
30
|
+
break;
|
|
31
|
+
default:
|
|
32
|
+
socket.write(`Comando desconocido para el módulo de tiempo: ${command}\n`);
|
|
33
|
+
socket.write(`Comandos disponibles: time, date\n\n`);
|
|
34
|
+
socket.write(`> `);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Muestra la hora actual en color azul
|
|
40
|
+
* @param {Object} socket - Socket de la conexión
|
|
41
|
+
*/
|
|
42
|
+
showTime(socket) {
|
|
43
|
+
const currentTime = new Date().toLocaleTimeString('es-ES', {
|
|
44
|
+
hour: '2-digit',
|
|
45
|
+
minute: '2-digit',
|
|
46
|
+
second: '2-digit',
|
|
47
|
+
hour12: false
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Enviar con código de color azul ANSI
|
|
51
|
+
socket.write(`\n\x1b[34mHora actual: ${currentTime}\x1b[0m\n\n`);
|
|
52
|
+
socket.write(`> `);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Muestra la fecha actual en color azul
|
|
57
|
+
* @param {Object} socket - Socket de la conexión
|
|
58
|
+
*/
|
|
59
|
+
showDate(socket) {
|
|
60
|
+
const currentDate = new Date().toLocaleDateString('es-ES', {
|
|
61
|
+
weekday: 'long',
|
|
62
|
+
year: 'numeric',
|
|
63
|
+
month: 'long',
|
|
64
|
+
day: 'numeric'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Enviar con código de color azul ANSI
|
|
68
|
+
socket.write(`\n\x1b[34mFecha actual: ${currentDate}\x1b[0m\n\n`);
|
|
69
|
+
socket.write(`> `);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Muestra la fecha y hora actual en color azul
|
|
74
|
+
* @param {Object} socket - Socket de la conexión
|
|
75
|
+
*/
|
|
76
|
+
showDateTime(socket) {
|
|
77
|
+
const now = new Date();
|
|
78
|
+
const dateTime = now.toLocaleString('es-ES', {
|
|
79
|
+
weekday: 'long',
|
|
80
|
+
year: 'numeric',
|
|
81
|
+
month: 'long',
|
|
82
|
+
day: 'numeric',
|
|
83
|
+
hour: '2-digit',
|
|
84
|
+
minute: '2-digit',
|
|
85
|
+
second: '2-digit',
|
|
86
|
+
hour12: false
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Enviar con código de color azul ANSI
|
|
90
|
+
socket.write(`\n\x1b[34mFecha y hora actual: ${dateTime}\x1b[0m\n\n`);
|
|
91
|
+
socket.write(`> `);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = TimeModule;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Módulo de Estadísticas del Caché de Vistas para la Extensión de Administración de JERK Framework
|
|
3
|
+
* Módulo personalizado para mostrar estadísticas del caché de vistas
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class ViewCacheStatsModule {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor del módulo de estadísticas del caché de vistas
|
|
9
|
+
* @param {Object} adminExtension - Instancia de la extensión de administración
|
|
10
|
+
*/
|
|
11
|
+
constructor(adminExtension) {
|
|
12
|
+
this.adminExtension = adminExtension;
|
|
13
|
+
this.name = 'View Cache Statistics Module';
|
|
14
|
+
this.description = 'Módulo para mostrar estadísticas del caché de vistas';
|
|
15
|
+
this.commands = ['view-cache'];
|
|
16
|
+
|
|
17
|
+
// Cargar el objeto global de estadísticas del caché de vistas
|
|
18
|
+
this.globalViewCacheInfo = require('../../utils/globalViewCacheInfo').globalViewCacheInfo;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Manejador para los comandos del módulo de estadísticas del caché de vistas
|
|
23
|
+
* @param {string} command - Comando a ejecutar
|
|
24
|
+
* @param {Object} socket - Socket de la conexión
|
|
25
|
+
*/
|
|
26
|
+
handleCommand(command, socket) {
|
|
27
|
+
switch (command) {
|
|
28
|
+
case 'view-cache':
|
|
29
|
+
case 'vcache':
|
|
30
|
+
case 'view-stats':
|
|
31
|
+
this.showViewCacheStats(socket);
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
socket.write(`Comando desconocido para el módulo de estadísticas del caché de vistas: ${command}\n`);
|
|
35
|
+
socket.write(`Comandos disponibles: view-cache, vcache, view-stats\n\n`);
|
|
36
|
+
socket.write(`> `);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Muestra estadísticas del caché de vistas
|
|
42
|
+
* @param {Object} socket - Socket de la conexión
|
|
43
|
+
*/
|
|
44
|
+
showViewCacheStats(socket) {
|
|
45
|
+
const { cacheStats, viewCache, viewDependencies } = this.globalViewCacheInfo;
|
|
46
|
+
|
|
47
|
+
// Codigos de color ANSI
|
|
48
|
+
const RESET = '\x1b[0m';
|
|
49
|
+
const BOLD = '\x1b[1m';
|
|
50
|
+
const GREEN = '\x1b[32m';
|
|
51
|
+
const YELLOW = '\x1b[33m';
|
|
52
|
+
const BLUE = '\x1b[34m';
|
|
53
|
+
const CYAN = '\x1b[36m';
|
|
54
|
+
const MAGENTA = '\x1b[35m';
|
|
55
|
+
|
|
56
|
+
socket.write(`\n${BOLD}${CYAN}=== Estadísticas del Caché de Vistas ===${RESET}\n`);
|
|
57
|
+
socket.write(`${GREEN}Vistas en caché:${RESET} ${viewCache.size}\n`);
|
|
58
|
+
socket.write(`${YELLOW}Hits (accesos exitosos):${RESET} ${cacheStats.hits}\n`);
|
|
59
|
+
socket.write(`${YELLOW}Misses (cargas desde disco):${RESET} ${cacheStats.misses}\n`);
|
|
60
|
+
socket.write(`${GREEN}Total de vistas únicas:${RESET} ${cacheStats.totalViews}\n`);
|
|
61
|
+
|
|
62
|
+
if (cacheStats.hits + cacheStats.misses > 0) {
|
|
63
|
+
const hitRate = (cacheStats.hits / (cacheStats.hits + cacheStats.misses) * 100).toFixed(2);
|
|
64
|
+
socket.write(`${BLUE}Tasa de aciertos:${RESET} ${hitRate}%\n`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Mostrar vistas más usadas (basado en el tamaño del caché)
|
|
68
|
+
if (viewCache.size > 0) {
|
|
69
|
+
socket.write(`\n${BOLD}${MAGENTA}Vistas en caché:${RESET}\n`);
|
|
70
|
+
for (const [viewPath, content] of viewCache) {
|
|
71
|
+
socket.write(` ${viewPath} (${content.length} chars)\n`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Mostrar dependencias de vistas
|
|
76
|
+
if (viewDependencies.size > 0) {
|
|
77
|
+
socket.write(`\n${BOLD}${MAGENTA}Dependencias de vistas (inclusiones):${RESET}\n`);
|
|
78
|
+
for (const [viewPath, dependencies] of viewDependencies) {
|
|
79
|
+
if (dependencies.size > 0) {
|
|
80
|
+
socket.write(` ${viewPath}:\n`);
|
|
81
|
+
for (const dependency of dependencies) {
|
|
82
|
+
socket.write(` - ${dependency}\n`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
socket.write(`\n${RESET}> `);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = ViewCacheStatsModule;
|