pms_md 1.0.0
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/README.md +93 -0
- package/node-monitor/ARCHITECTURE.md +341 -0
- package/node-monitor/CHANGELOG.md +105 -0
- package/node-monitor/CONTRIBUTING.md +96 -0
- package/node-monitor/DESIGN_IMPROVEMENTS.md +286 -0
- package/node-monitor/FILTER_BUTTONS_FIX.md +303 -0
- package/node-monitor/GETTING_STARTED.md +416 -0
- package/node-monitor/INSTALLATION.md +470 -0
- package/node-monitor/LICENSE +22 -0
- package/node-monitor/PUBLISHING_GUIDE.md +331 -0
- package/node-monitor/QUICK_REFERENCE.md +252 -0
- package/node-monitor/README.md +458 -0
- package/node-monitor/READY_TO_PUBLISH.md +272 -0
- package/node-monitor/SETUP_GUIDE.md +479 -0
- package/node-monitor/examples/EMAIL_SETUP_GUIDE.md +282 -0
- package/node-monitor/examples/ERROR_LOGGING_GUIDE.md +405 -0
- package/node-monitor/examples/GET_APP_PASSWORD.md +145 -0
- package/node-monitor/examples/LOG_FILES_REFERENCE.md +336 -0
- package/node-monitor/examples/QUICK_START_EMAIL.md +126 -0
- package/node-monitor/examples/express-app.js +499 -0
- package/node-monitor/examples/package-lock.json +1295 -0
- package/node-monitor/examples/package.json +18 -0
- package/node-monitor/examples/public/css/style.css +718 -0
- package/node-monitor/examples/public/js/dashboard.js +207 -0
- package/node-monitor/examples/public/js/health.js +114 -0
- package/node-monitor/examples/public/js/main.js +89 -0
- package/node-monitor/examples/public/js/metrics.js +225 -0
- package/node-monitor/examples/public/js/theme.js +138 -0
- package/node-monitor/examples/views/dashboard.ejs +20 -0
- package/node-monitor/examples/views/error-logs.ejs +1129 -0
- package/node-monitor/examples/views/health.ejs +21 -0
- package/node-monitor/examples/views/home.ejs +341 -0
- package/node-monitor/examples/views/layout.ejs +50 -0
- package/node-monitor/examples/views/metrics.ejs +16 -0
- package/node-monitor/examples/views/partials/footer.ejs +16 -0
- package/node-monitor/examples/views/partials/header.ejs +35 -0
- package/node-monitor/examples/views/partials/nav.ejs +23 -0
- package/node-monitor/examples/views/status.ejs +390 -0
- package/node-monitor/package-lock.json +4300 -0
- package/node-monitor/package.json +76 -0
- package/node-monitor/pre-publish-check.js +200 -0
- package/node-monitor/src/config/monitoringConfig.js +255 -0
- package/node-monitor/src/index.js +300 -0
- package/node-monitor/src/logger/errorLogger.js +297 -0
- package/node-monitor/src/monitors/apiErrorMonitor.js +156 -0
- package/node-monitor/src/monitors/dbConnectionMonitor.js +389 -0
- package/node-monitor/src/monitors/serverHealthMonitor.js +320 -0
- package/node-monitor/src/monitors/systemResourceMonitor.js +357 -0
- package/node-monitor/src/notifiers/emailNotifier.js +248 -0
- package/node-monitor/src/notifiers/notificationManager.js +96 -0
- package/node-monitor/src/notifiers/slackNotifier.js +209 -0
- package/node-monitor/src/views/dashboard.html +530 -0
- package/node-monitor/src/views/health.html +399 -0
- package/node-monitor/src/views/metrics.html +406 -0
- package/package.json +22 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Metrics - Node Monitor</title>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
body {
|
|
16
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
17
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
padding: 20px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.container {
|
|
23
|
+
max-width: 1400px;
|
|
24
|
+
margin: 0 auto;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.header {
|
|
28
|
+
background: white;
|
|
29
|
+
border-radius: 15px;
|
|
30
|
+
padding: 30px;
|
|
31
|
+
margin-bottom: 30px;
|
|
32
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.header h1 {
|
|
36
|
+
color: #333;
|
|
37
|
+
font-size: 2.5em;
|
|
38
|
+
margin-bottom: 10px;
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: 15px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.card {
|
|
45
|
+
background: white;
|
|
46
|
+
border-radius: 15px;
|
|
47
|
+
padding: 30px;
|
|
48
|
+
margin-bottom: 20px;
|
|
49
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.card h2 {
|
|
53
|
+
color: #333;
|
|
54
|
+
margin-bottom: 20px;
|
|
55
|
+
padding-bottom: 15px;
|
|
56
|
+
border-bottom: 2px solid #f0f0f0;
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 10px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.chart-container {
|
|
63
|
+
position: relative;
|
|
64
|
+
height: 300px;
|
|
65
|
+
margin-top: 20px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.stats-grid {
|
|
69
|
+
display: grid;
|
|
70
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
71
|
+
gap: 20px;
|
|
72
|
+
margin-bottom: 30px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.stat-card {
|
|
76
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
77
|
+
padding: 25px;
|
|
78
|
+
border-radius: 12px;
|
|
79
|
+
color: white;
|
|
80
|
+
text-align: center;
|
|
81
|
+
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.stat-value {
|
|
85
|
+
font-size: 2.5em;
|
|
86
|
+
font-weight: bold;
|
|
87
|
+
margin: 10px 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.stat-label {
|
|
91
|
+
font-size: 0.95em;
|
|
92
|
+
opacity: 0.9;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.stat-change {
|
|
96
|
+
font-size: 0.85em;
|
|
97
|
+
margin-top: 5px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.refresh-btn {
|
|
101
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
102
|
+
color: white;
|
|
103
|
+
border: none;
|
|
104
|
+
padding: 12px 30px;
|
|
105
|
+
border-radius: 25px;
|
|
106
|
+
font-size: 1em;
|
|
107
|
+
font-weight: bold;
|
|
108
|
+
cursor: pointer;
|
|
109
|
+
transition: transform 0.2s ease;
|
|
110
|
+
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.refresh-btn:hover {
|
|
114
|
+
transform: scale(1.05);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.nav-links {
|
|
118
|
+
display: flex;
|
|
119
|
+
gap: 15px;
|
|
120
|
+
margin-top: 15px;
|
|
121
|
+
flex-wrap: wrap;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.nav-link {
|
|
125
|
+
color: #667eea;
|
|
126
|
+
text-decoration: none;
|
|
127
|
+
padding: 8px 16px;
|
|
128
|
+
background: #f0f0f0;
|
|
129
|
+
border-radius: 8px;
|
|
130
|
+
transition: all 0.3s ease;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.nav-link:hover {
|
|
134
|
+
background: #667eea;
|
|
135
|
+
color: white;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.timestamp {
|
|
139
|
+
text-align: center;
|
|
140
|
+
color: white;
|
|
141
|
+
margin-top: 20px;
|
|
142
|
+
font-size: 0.95em;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.loading {
|
|
146
|
+
text-align: center;
|
|
147
|
+
padding: 40px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.spinner {
|
|
151
|
+
border: 4px solid #f3f4f6;
|
|
152
|
+
border-top: 4px solid #667eea;
|
|
153
|
+
border-radius: 50%;
|
|
154
|
+
width: 50px;
|
|
155
|
+
height: 50px;
|
|
156
|
+
animation: spin 1s linear infinite;
|
|
157
|
+
margin: 0 auto 20px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@keyframes spin {
|
|
161
|
+
0% { transform: rotate(0deg); }
|
|
162
|
+
100% { transform: rotate(360deg); }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@media (max-width: 768px) {
|
|
166
|
+
.header h1 {
|
|
167
|
+
font-size: 1.8em;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.stats-grid {
|
|
171
|
+
grid-template-columns: 1fr;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
</style>
|
|
175
|
+
</head>
|
|
176
|
+
<body>
|
|
177
|
+
<div class="container">
|
|
178
|
+
<div class="header">
|
|
179
|
+
<h1>📈 System Metrics</h1>
|
|
180
|
+
<p style="color: #666; margin-top: 10px;">Real-time performance monitoring and analytics</p>
|
|
181
|
+
<div class="nav-links">
|
|
182
|
+
<a href="/monitor/dashboard" class="nav-link">📊 Dashboard</a>
|
|
183
|
+
<a href="/health" class="nav-link">💚 Health</a>
|
|
184
|
+
<a href="/monitor/metrics" class="nav-link">📈 Metrics</a>
|
|
185
|
+
<a href="/monitor/status" class="nav-link">📋 Status</a>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<div id="statsContent">
|
|
190
|
+
<div class="loading">
|
|
191
|
+
<div class="spinner"></div>
|
|
192
|
+
<p>Loading metrics data...</p>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<div id="chartsContent"></div>
|
|
197
|
+
|
|
198
|
+
<div style="text-align: center; margin-top: 20px;">
|
|
199
|
+
<button class="refresh-btn" onclick="loadMetrics()">🔄 Refresh Metrics</button>
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<div class="timestamp" id="lastUpdate"></div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<script>
|
|
206
|
+
let cpuChart = null;
|
|
207
|
+
let memoryChart = null;
|
|
208
|
+
|
|
209
|
+
async function loadMetrics() {
|
|
210
|
+
try {
|
|
211
|
+
const response = await fetch('/monitor/metrics');
|
|
212
|
+
const data = await response.json();
|
|
213
|
+
renderMetrics(data);
|
|
214
|
+
updateTimestamp();
|
|
215
|
+
} catch (error) {
|
|
216
|
+
document.getElementById('statsContent').innerHTML = `
|
|
217
|
+
<div class="card">
|
|
218
|
+
<h2 style="color: #ef4444;">❌ Error Loading Metrics</h2>
|
|
219
|
+
<p>${error.message}</p>
|
|
220
|
+
</div>
|
|
221
|
+
`;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function renderMetrics(data) {
|
|
226
|
+
renderStats(data);
|
|
227
|
+
renderCharts(data);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function renderStats(data) {
|
|
231
|
+
const latest = data.history && data.history.length > 0
|
|
232
|
+
? data.history[data.history.length - 1]
|
|
233
|
+
: { cpu: {}, memory: {} };
|
|
234
|
+
|
|
235
|
+
const html = `
|
|
236
|
+
<div class="stats-grid">
|
|
237
|
+
<div class="stat-card">
|
|
238
|
+
<div class="stat-label">CPU Usage (Process)</div>
|
|
239
|
+
<div class="stat-value">${(latest.cpu?.process || 0).toFixed(1)}%</div>
|
|
240
|
+
<div class="stat-change">Current load</div>
|
|
241
|
+
</div>
|
|
242
|
+
<div class="stat-card">
|
|
243
|
+
<div class="stat-label">CPU Usage (System)</div>
|
|
244
|
+
<div class="stat-value">${(latest.cpu?.system || 0).toFixed(1)}%</div>
|
|
245
|
+
<div class="stat-change">Overall system</div>
|
|
246
|
+
</div>
|
|
247
|
+
<div class="stat-card">
|
|
248
|
+
<div class="stat-label">Memory Usage</div>
|
|
249
|
+
<div class="stat-value">${(latest.memory?.percentUsed || 0).toFixed(1)}%</div>
|
|
250
|
+
<div class="stat-change">${formatBytes(latest.memory?.heapUsed || 0)} used</div>
|
|
251
|
+
</div>
|
|
252
|
+
<div class="stat-card">
|
|
253
|
+
<div class="stat-label">Data Points</div>
|
|
254
|
+
<div class="stat-value">${data.history?.length || 0}</div>
|
|
255
|
+
<div class="stat-change">Collected samples</div>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
`;
|
|
259
|
+
|
|
260
|
+
document.getElementById('statsContent').innerHTML = html;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function renderCharts(data) {
|
|
264
|
+
if (!data.history || data.history.length === 0) {
|
|
265
|
+
document.getElementById('chartsContent').innerHTML = `
|
|
266
|
+
<div class="card">
|
|
267
|
+
<p style="text-align: center; color: #666;">No metrics history available yet</p>
|
|
268
|
+
</div>
|
|
269
|
+
`;
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const labels = data.history.map((_, index) => `${index + 1}`);
|
|
274
|
+
const cpuProcessData = data.history.map(m => m.cpu?.process || 0);
|
|
275
|
+
const cpuSystemData = data.history.map(m => m.cpu?.system || 0);
|
|
276
|
+
const memoryData = data.history.map(m => m.memory?.percentUsed || 0);
|
|
277
|
+
|
|
278
|
+
document.getElementById('chartsContent').innerHTML = `
|
|
279
|
+
<div class="card">
|
|
280
|
+
<h2>💻 CPU Usage Over Time</h2>
|
|
281
|
+
<div class="chart-container">
|
|
282
|
+
<canvas id="cpuChart"></canvas>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
|
|
286
|
+
<div class="card">
|
|
287
|
+
<h2>🧠 Memory Usage Over Time</h2>
|
|
288
|
+
<div class="chart-container">
|
|
289
|
+
<canvas id="memoryChart"></canvas>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
`;
|
|
293
|
+
|
|
294
|
+
// Destroy existing charts
|
|
295
|
+
if (cpuChart) cpuChart.destroy();
|
|
296
|
+
if (memoryChart) memoryChart.destroy();
|
|
297
|
+
|
|
298
|
+
// Create CPU chart
|
|
299
|
+
const cpuCtx = document.getElementById('cpuChart').getContext('2d');
|
|
300
|
+
cpuChart = new Chart(cpuCtx, {
|
|
301
|
+
type: 'line',
|
|
302
|
+
data: {
|
|
303
|
+
labels: labels,
|
|
304
|
+
datasets: [
|
|
305
|
+
{
|
|
306
|
+
label: 'Process CPU %',
|
|
307
|
+
data: cpuProcessData,
|
|
308
|
+
borderColor: '#667eea',
|
|
309
|
+
backgroundColor: 'rgba(102, 126, 234, 0.1)',
|
|
310
|
+
tension: 0.4,
|
|
311
|
+
fill: true
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
label: 'System CPU %',
|
|
315
|
+
data: cpuSystemData,
|
|
316
|
+
borderColor: '#764ba2',
|
|
317
|
+
backgroundColor: 'rgba(118, 75, 162, 0.1)',
|
|
318
|
+
tension: 0.4,
|
|
319
|
+
fill: true
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
},
|
|
323
|
+
options: {
|
|
324
|
+
responsive: true,
|
|
325
|
+
maintainAspectRatio: false,
|
|
326
|
+
plugins: {
|
|
327
|
+
legend: {
|
|
328
|
+
display: true,
|
|
329
|
+
position: 'top'
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
scales: {
|
|
333
|
+
y: {
|
|
334
|
+
beginAtZero: true,
|
|
335
|
+
max: 100,
|
|
336
|
+
ticks: {
|
|
337
|
+
callback: function(value) {
|
|
338
|
+
return value + '%';
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Create Memory chart
|
|
347
|
+
const memoryCtx = document.getElementById('memoryChart').getContext('2d');
|
|
348
|
+
memoryChart = new Chart(memoryCtx, {
|
|
349
|
+
type: 'line',
|
|
350
|
+
data: {
|
|
351
|
+
labels: labels,
|
|
352
|
+
datasets: [{
|
|
353
|
+
label: 'Memory Usage %',
|
|
354
|
+
data: memoryData,
|
|
355
|
+
borderColor: '#10b981',
|
|
356
|
+
backgroundColor: 'rgba(16, 185, 129, 0.1)',
|
|
357
|
+
tension: 0.4,
|
|
358
|
+
fill: true
|
|
359
|
+
}]
|
|
360
|
+
},
|
|
361
|
+
options: {
|
|
362
|
+
responsive: true,
|
|
363
|
+
maintainAspectRatio: false,
|
|
364
|
+
plugins: {
|
|
365
|
+
legend: {
|
|
366
|
+
display: true,
|
|
367
|
+
position: 'top'
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
scales: {
|
|
371
|
+
y: {
|
|
372
|
+
beginAtZero: true,
|
|
373
|
+
max: 100,
|
|
374
|
+
ticks: {
|
|
375
|
+
callback: function(value) {
|
|
376
|
+
return value + '%';
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function formatBytes(bytes) {
|
|
386
|
+
if (bytes === 0) return '0 B';
|
|
387
|
+
const k = 1024;
|
|
388
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
389
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
390
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function updateTimestamp() {
|
|
394
|
+
const now = new Date().toLocaleString();
|
|
395
|
+
document.getElementById('lastUpdate').textContent = `Last updated: ${now}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Load metrics on page load
|
|
399
|
+
loadMetrics();
|
|
400
|
+
|
|
401
|
+
// Auto-refresh every 30 seconds
|
|
402
|
+
setInterval(loadMetrics, 30000);
|
|
403
|
+
</script>
|
|
404
|
+
</body>
|
|
405
|
+
</html>
|
|
406
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pms_md",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "To make it easy for you to get started with GitLab, here's a list of recommended next steps.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://gitlab.com/manish-proses/pms_md.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"proses"
|
|
15
|
+
],
|
|
16
|
+
"author": "Manish Desai",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://gitlab.com/manish-proses/pms_md/issues"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://gitlab.com/manish-proses/pms_md#readme"
|
|
22
|
+
}
|