@gazzehamine/armada-watch-agent 1.4.1 → 1.4.3
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/dist/collector.js +85 -0
- package/dist/index.js +7 -1
- package/package.json +2 -2
package/dist/collector.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.getSystemInfo = getSystemInfo;
|
|
|
7
7
|
exports.collectMetrics = collectMetrics;
|
|
8
8
|
exports.collectProcesses = collectProcesses;
|
|
9
9
|
exports.collectDockerContainers = collectDockerContainers;
|
|
10
|
+
exports.collectNginxMetrics = collectNginxMetrics;
|
|
11
|
+
exports.collectPM2Processes = collectPM2Processes;
|
|
10
12
|
exports.collectSSLCertificates = collectSSLCertificates;
|
|
11
13
|
const systeminformation_1 = __importDefault(require("systeminformation"));
|
|
12
14
|
const os_1 = __importDefault(require("os"));
|
|
@@ -262,6 +264,89 @@ async function getCertificateInfo(certPath, domain) {
|
|
|
262
264
|
return null;
|
|
263
265
|
}
|
|
264
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Collect Nginx metrics from stub_status
|
|
269
|
+
*/
|
|
270
|
+
async function collectNginxMetrics() {
|
|
271
|
+
try {
|
|
272
|
+
// Try common nginx stub_status URLs
|
|
273
|
+
const urls = [
|
|
274
|
+
'http://localhost/nginx_status',
|
|
275
|
+
'http://localhost:80/nginx_status',
|
|
276
|
+
'http://127.0.0.1/nginx_status',
|
|
277
|
+
'http://localhost/status',
|
|
278
|
+
];
|
|
279
|
+
for (const url of urls) {
|
|
280
|
+
try {
|
|
281
|
+
const { stdout } = await execAsync(`curl -s ${url} --max-time 2`, { timeout: 3000 });
|
|
282
|
+
if (stdout && stdout.includes('Active connections')) {
|
|
283
|
+
// Parse nginx stub_status output
|
|
284
|
+
// Example:
|
|
285
|
+
// Active connections: 2
|
|
286
|
+
// server accepts handled requests
|
|
287
|
+
// 123 123 456
|
|
288
|
+
// Reading: 0 Writing: 1 Waiting: 1
|
|
289
|
+
const activeMatch = stdout.match(/Active connections:\s+(\d+)/);
|
|
290
|
+
const serverMatch = stdout.match(/\s+(\d+)\s+(\d+)\s+(\d+)/);
|
|
291
|
+
const rwwMatch = stdout.match(/Reading:\s+(\d+)\s+Writing:\s+(\d+)\s+Waiting:\s+(\d+)/);
|
|
292
|
+
if (activeMatch && serverMatch && rwwMatch) {
|
|
293
|
+
const accepts = parseInt(serverMatch[1]);
|
|
294
|
+
const handled = parseInt(serverMatch[2]);
|
|
295
|
+
const requests = parseInt(serverMatch[3]);
|
|
296
|
+
// Calculate per-second rates (will be calculated from deltas in the backend)
|
|
297
|
+
return {
|
|
298
|
+
activeConnections: parseInt(activeMatch[1]),
|
|
299
|
+
accepts,
|
|
300
|
+
handled,
|
|
301
|
+
requests,
|
|
302
|
+
reading: parseInt(rwwMatch[1]),
|
|
303
|
+
writing: parseInt(rwwMatch[2]),
|
|
304
|
+
waiting: parseInt(rwwMatch[3]),
|
|
305
|
+
requestsPerSecond: 0, // Will be calculated from deltas
|
|
306
|
+
connectionsPerSecond: 0, // Will be calculated from deltas
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
// Try next URL
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Nginx not available or stub_status not configured
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Collect PM2 process information
|
|
325
|
+
*/
|
|
326
|
+
async function collectPM2Processes() {
|
|
327
|
+
try {
|
|
328
|
+
// Execute pm2 jlist command to get JSON output
|
|
329
|
+
const { stdout } = await execAsync('pm2 jlist');
|
|
330
|
+
const pm2Processes = JSON.parse(stdout);
|
|
331
|
+
return pm2Processes.map((proc) => ({
|
|
332
|
+
pmId: proc.pm_id || 0,
|
|
333
|
+
name: proc.name || 'unknown',
|
|
334
|
+
version: proc.pm2_env?.version || 'unknown',
|
|
335
|
+
mode: proc.pm2_env?.exec_mode || 'unknown',
|
|
336
|
+
pid: proc.pid || 0,
|
|
337
|
+
uptime: proc.pm2_env?.pm_uptime || 0,
|
|
338
|
+
restarts: proc.pm2_env?.restart_time || 0,
|
|
339
|
+
status: proc.pm2_env?.status || 'unknown',
|
|
340
|
+
cpu: proc.monit?.cpu || 0,
|
|
341
|
+
memory: proc.monit?.memory || 0,
|
|
342
|
+
user: proc.pm2_env?.username || 'unknown',
|
|
343
|
+
}));
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
// PM2 not installed or no processes running
|
|
347
|
+
return [];
|
|
348
|
+
}
|
|
349
|
+
}
|
|
265
350
|
/**
|
|
266
351
|
* Collect SSL certificate information from Certbot certificates
|
|
267
352
|
*/
|
package/dist/index.js
CHANGED
|
@@ -75,6 +75,8 @@ async function sendMetrics() {
|
|
|
75
75
|
const metrics = await (0, collector_1.collectMetrics)();
|
|
76
76
|
const processes = await (0, collector_1.collectProcesses)();
|
|
77
77
|
const dockerContainers = await (0, collector_1.collectDockerContainers)();
|
|
78
|
+
const pm2Processes = await (0, collector_1.collectPM2Processes)();
|
|
79
|
+
const nginxMetrics = await (0, collector_1.collectNginxMetrics)();
|
|
78
80
|
// Check if it's time to refresh SSL certificates (every 5 minutes)
|
|
79
81
|
const now = Date.now();
|
|
80
82
|
const shouldCheckSSL = (now - lastSSLCheckTime) >= SSL_CHECK_INTERVAL;
|
|
@@ -93,13 +95,17 @@ async function sendMetrics() {
|
|
|
93
95
|
},
|
|
94
96
|
processes,
|
|
95
97
|
dockerContainers,
|
|
98
|
+
pm2Processes: pm2Processes.length > 0 ? pm2Processes : undefined,
|
|
99
|
+
nginxMetrics: nginxMetrics || undefined,
|
|
96
100
|
// Always send SSL certificates if we have them (from startup or last check)
|
|
97
101
|
sslCertificates: lastSSLCertificates.length > 0 ? lastSSLCertificates : undefined,
|
|
98
102
|
};
|
|
99
103
|
await axios_1.default.post(`${SERVER_URL}/api/metrics`, payload, {
|
|
100
104
|
timeout: 5000,
|
|
101
105
|
});
|
|
102
|
-
|
|
106
|
+
const pm2Info = pm2Processes.length > 0 ? ` | PM2: ${pm2Processes.length}` : '';
|
|
107
|
+
const nginxInfo = nginxMetrics ? ` | Nginx: ${nginxMetrics.activeConnections} conn` : '';
|
|
108
|
+
console.log(`✓ Metrics sent successfully - CPU: ${metrics.cpuUsage.toFixed(1)}% | Memory: ${metrics.memoryUsage.toFixed(1)}%${pm2Info}${nginxInfo}`);
|
|
103
109
|
}
|
|
104
110
|
catch (error) {
|
|
105
111
|
if (axios_1.default.isAxiosError(error)) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gazzehamine/armada-watch-agent",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "Monitoring agent for Armada Watch - EC2 instance monitoring with SSL
|
|
3
|
+
"version": "1.4.3",
|
|
4
|
+
"description": "Monitoring agent for Armada Watch - EC2 instance monitoring with SSL, PM2, and Nginx monitoring",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"armada-watch-agent": "dist/index.js"
|