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,21 @@
|
|
|
1
|
+
<%- include('partials/header') %>
|
|
2
|
+
|
|
3
|
+
<div class="health-header">
|
|
4
|
+
<div class="status-indicator" id="statusIndicator">
|
|
5
|
+
<div class="pulse"></div>
|
|
6
|
+
<span id="statusText">Checking health...</span>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div id="healthContent">
|
|
11
|
+
<div class="loading">
|
|
12
|
+
<div class="spinner"></div>
|
|
13
|
+
<p>Loading health data...</p>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="action-buttons">
|
|
18
|
+
<button class="refresh-btn" onclick="loadHealth()">🔄 Refresh Health Check</button>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<%- include('partials/footer') %>
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
<%- include('partials/header') %>
|
|
2
|
+
|
|
3
|
+
<div class="home-container">
|
|
4
|
+
<div class="hero">
|
|
5
|
+
<h1 class="hero-title">📊 Project Monitoring System</h1>
|
|
6
|
+
<p class="hero-subtitle">Real-time Application Monitoring & Health Checks</p>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div class="links-grid">
|
|
10
|
+
<a href="/monitor/dashboard" class="link-card">
|
|
11
|
+
<div class="link-icon">📊</div>
|
|
12
|
+
<div class="link-title">Dashboard</div>
|
|
13
|
+
<div class="link-desc">Complete monitoring overview</div>
|
|
14
|
+
</a>
|
|
15
|
+
|
|
16
|
+
<a href="/health" class="link-card">
|
|
17
|
+
<div class="link-icon">💚</div>
|
|
18
|
+
<div class="link-title">Health Check</div>
|
|
19
|
+
<div class="link-desc">System health status</div>
|
|
20
|
+
</a>
|
|
21
|
+
|
|
22
|
+
<a href="/monitor/metrics" class="link-card">
|
|
23
|
+
<div class="link-icon">📈</div>
|
|
24
|
+
<div class="link-title">Metrics</div>
|
|
25
|
+
<div class="link-desc">Performance charts</div>
|
|
26
|
+
</a>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="api-section">
|
|
30
|
+
<h2>🔧 Test Endpoints</h2>
|
|
31
|
+
<div class="api-links">
|
|
32
|
+
<button onclick="testEndpoint('/api/success', 'Success')" class="api-link">✓ Success</button>
|
|
33
|
+
<button onclick="testEndpoint('/api/error', 'Error')" class="api-link">✗ Error</button>
|
|
34
|
+
<button onclick="testEndpoint('/api/slow', 'Slow Request')" class="api-link">⏱ Slow Request</button>
|
|
35
|
+
<button onclick="testEndpoint('/monitor/status?format=json', 'Status JSON')" class="api-link">📋 Status JSON</button>
|
|
36
|
+
<button onclick="testEndpoint('/api/notify-test', 'Test Email')" class="api-link" style="background: linear-gradient(135deg, #10b981, #059669); color: white; border: none;">📧 Test Email</button>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<!-- Modal for API responses -->
|
|
41
|
+
<div id="apiModal" class="modal">
|
|
42
|
+
<div class="modal-content">
|
|
43
|
+
<span class="modal-close" onclick="closeModal()">×</span>
|
|
44
|
+
<h2 id="modalTitle">API Response</h2>
|
|
45
|
+
<div id="modalBody"></div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<style>
|
|
50
|
+
.modal {
|
|
51
|
+
display: none;
|
|
52
|
+
position: fixed;
|
|
53
|
+
z-index: 999;
|
|
54
|
+
left: 0;
|
|
55
|
+
top: 0;
|
|
56
|
+
width: 100%;
|
|
57
|
+
height: 100%;
|
|
58
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
59
|
+
animation: fadeIn 0.3s ease;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@keyframes fadeIn {
|
|
63
|
+
from { opacity: 0; }
|
|
64
|
+
to { opacity: 1; }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.modal-content {
|
|
68
|
+
background: var(--card-bg);
|
|
69
|
+
margin: 10% auto;
|
|
70
|
+
padding: 30px;
|
|
71
|
+
border-radius: 12px;
|
|
72
|
+
width: 90%;
|
|
73
|
+
max-width: 600px;
|
|
74
|
+
box-shadow: 0 10px 40px var(--card-shadow);
|
|
75
|
+
animation: slideDown 0.3s ease;
|
|
76
|
+
position: relative;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes slideDown {
|
|
80
|
+
from {
|
|
81
|
+
transform: translateY(-50px);
|
|
82
|
+
opacity: 0;
|
|
83
|
+
}
|
|
84
|
+
to {
|
|
85
|
+
transform: translateY(0);
|
|
86
|
+
opacity: 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.modal-close {
|
|
91
|
+
position: absolute;
|
|
92
|
+
right: 20px;
|
|
93
|
+
top: 20px;
|
|
94
|
+
font-size: 28px;
|
|
95
|
+
font-weight: bold;
|
|
96
|
+
color: var(--text-secondary);
|
|
97
|
+
cursor: pointer;
|
|
98
|
+
transition: color 0.2s;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.modal-close:hover {
|
|
102
|
+
color: var(--text-primary);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#modalTitle {
|
|
106
|
+
margin-top: 0;
|
|
107
|
+
color: var(--text-primary);
|
|
108
|
+
font-size: 1.5em;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#modalBody {
|
|
112
|
+
margin-top: 20px;
|
|
113
|
+
padding: 20px;
|
|
114
|
+
background: var(--nav-bg);
|
|
115
|
+
border-radius: 8px;
|
|
116
|
+
border-left: 4px solid #667eea;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.api-link {
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
border: none;
|
|
122
|
+
font-family: inherit;
|
|
123
|
+
font-size: inherit;
|
|
124
|
+
text-align: center;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.response-success {
|
|
128
|
+
color: #10b981;
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.response-error {
|
|
133
|
+
color: #ef4444;
|
|
134
|
+
font-weight: 600;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.response-data {
|
|
138
|
+
background: #1f2937;
|
|
139
|
+
color: #10b981;
|
|
140
|
+
padding: 15px;
|
|
141
|
+
border-radius: 6px;
|
|
142
|
+
font-family: 'Courier New', monospace;
|
|
143
|
+
margin-top: 10px;
|
|
144
|
+
overflow-x: auto;
|
|
145
|
+
position: relative;
|
|
146
|
+
max-height: 400px;
|
|
147
|
+
overflow-y: auto;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.copy-btn {
|
|
151
|
+
position: absolute;
|
|
152
|
+
top: 10px;
|
|
153
|
+
right: 10px;
|
|
154
|
+
background: #667eea;
|
|
155
|
+
color: white;
|
|
156
|
+
border: none;
|
|
157
|
+
padding: 6px 12px;
|
|
158
|
+
border-radius: 4px;
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
font-size: 0.85em;
|
|
161
|
+
transition: background 0.2s;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.copy-btn:hover {
|
|
165
|
+
background: #5568d3;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.copy-btn.copied {
|
|
169
|
+
background: #10b981;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.loading {
|
|
173
|
+
display: inline-block;
|
|
174
|
+
width: 20px;
|
|
175
|
+
height: 20px;
|
|
176
|
+
border: 3px solid #f3f3f3;
|
|
177
|
+
border-top: 3px solid #667eea;
|
|
178
|
+
border-radius: 50%;
|
|
179
|
+
animation: spin 1s linear infinite;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@keyframes spin {
|
|
183
|
+
0% { transform: rotate(0deg); }
|
|
184
|
+
100% { transform: rotate(360deg); }
|
|
185
|
+
}
|
|
186
|
+
</style>
|
|
187
|
+
|
|
188
|
+
<script>
|
|
189
|
+
async function testEndpoint(url, name) {
|
|
190
|
+
const modal = document.getElementById('apiModal');
|
|
191
|
+
const modalTitle = document.getElementById('modalTitle');
|
|
192
|
+
const modalBody = document.getElementById('modalBody');
|
|
193
|
+
|
|
194
|
+
// Show modal with loading state
|
|
195
|
+
modalTitle.textContent = `Testing: ${name}`;
|
|
196
|
+
modalBody.innerHTML = '<div class="loading"></div> <span style="margin-left: 10px;">Calling API...</span>';
|
|
197
|
+
modal.style.display = 'block';
|
|
198
|
+
|
|
199
|
+
const startTime = Date.now();
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const response = await fetch(url);
|
|
203
|
+
const duration = Date.now() - startTime;
|
|
204
|
+
const data = await response.json();
|
|
205
|
+
|
|
206
|
+
const jsonString = JSON.stringify(data, null, 2);
|
|
207
|
+
|
|
208
|
+
// Special handling for email test response
|
|
209
|
+
if (name === 'Test Email' && data.result && data.result.status === 'fulfilled') {
|
|
210
|
+
const emailData = data.result.value;
|
|
211
|
+
modalBody.innerHTML = `
|
|
212
|
+
<div class="response-success">✓ Email Sent Successfully!</div>
|
|
213
|
+
<div style="margin-top: 15px; padding: 15px; background: #f0fdf4; border-left: 4px solid #10b981; border-radius: 6px;">
|
|
214
|
+
<div style="color: #065f46; margin-bottom: 8px;">
|
|
215
|
+
<strong>📧 Email Details:</strong>
|
|
216
|
+
</div>
|
|
217
|
+
<div style="color: #047857; font-size: 0.95em; line-height: 1.6;">
|
|
218
|
+
<strong>Message:</strong> ${emailData.message || 'Test notification sent'}<br>
|
|
219
|
+
<strong>To:</strong> ${emailData.instructions || 'Check your email inbox at manish.prajapati@gmail.com'}<br>
|
|
220
|
+
<strong>Duration:</strong> ${duration}ms
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
<div style="margin-top: 15px; padding: 12px; background: #eff6ff; border-left: 4px solid #3b82f6; border-radius: 6px;">
|
|
224
|
+
<div style="color: #1e40af; font-size: 0.9em;">
|
|
225
|
+
💡 <strong>Tip:</strong> Check your email inbox for the test notification
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
<details style="margin-top: 15px;">
|
|
229
|
+
<summary style="cursor: pointer; color: #6b7280; font-weight: 600; padding: 8px; background: #f9fafb; border-radius: 4px;">
|
|
230
|
+
📋 View Full Response
|
|
231
|
+
</summary>
|
|
232
|
+
<div style="position: relative; margin-top: 10px;">
|
|
233
|
+
<button class="copy-btn" onclick="copyJSON(this, \`${jsonString.replace(/`/g, '\\`')}\`)">📋 Copy</button>
|
|
234
|
+
<div class="response-data">${jsonString}</div>
|
|
235
|
+
</div>
|
|
236
|
+
</details>
|
|
237
|
+
`;
|
|
238
|
+
} else if (response.ok) {
|
|
239
|
+
modalBody.innerHTML = `
|
|
240
|
+
<div class="response-success">✓ Success (${response.status})</div>
|
|
241
|
+
<div style="margin-top: 10px; color: #6b7280;">
|
|
242
|
+
<strong>Duration:</strong> ${duration}ms<br>
|
|
243
|
+
<strong>Status:</strong> ${response.status} ${response.statusText}
|
|
244
|
+
</div>
|
|
245
|
+
<div style="position: relative;">
|
|
246
|
+
<button class="copy-btn" onclick="copyJSON(this, \`${jsonString.replace(/`/g, '\\`')}\`)">📋 Copy</button>
|
|
247
|
+
<div class="response-data">${jsonString}</div>
|
|
248
|
+
</div>
|
|
249
|
+
`;
|
|
250
|
+
} else {
|
|
251
|
+
modalBody.innerHTML = `
|
|
252
|
+
<div class="response-error">✗ Error (${response.status})</div>
|
|
253
|
+
<div style="margin-top: 10px; color: #6b7280;">
|
|
254
|
+
<strong>Duration:</strong> ${duration}ms<br>
|
|
255
|
+
<strong>Status:</strong> ${response.status} ${response.statusText}
|
|
256
|
+
</div>
|
|
257
|
+
<div style="position: relative;">
|
|
258
|
+
<button class="copy-btn" onclick="copyJSON(this, \`${jsonString.replace(/`/g, '\\`')}\`)">📋 Copy</button>
|
|
259
|
+
<div class="response-data">${jsonString}</div>
|
|
260
|
+
</div>
|
|
261
|
+
`;
|
|
262
|
+
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
const duration = Date.now() - startTime;
|
|
265
|
+
modalBody.innerHTML = `
|
|
266
|
+
<div class="response-error">✗ Request Failed</div>
|
|
267
|
+
<div style="margin-top: 10px; color: #6b7280;">
|
|
268
|
+
<strong>Duration:</strong> ${duration}ms<br>
|
|
269
|
+
<strong>Error:</strong> ${error.message}
|
|
270
|
+
</div>
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function closeModal() {
|
|
276
|
+
document.getElementById('apiModal').style.display = 'none';
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function copyJSON(button, text) {
|
|
280
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
281
|
+
const originalText = button.textContent;
|
|
282
|
+
button.textContent = '✓ Copied!';
|
|
283
|
+
button.classList.add('copied');
|
|
284
|
+
|
|
285
|
+
setTimeout(() => {
|
|
286
|
+
button.textContent = originalText;
|
|
287
|
+
button.classList.remove('copied');
|
|
288
|
+
}, 2000);
|
|
289
|
+
}).catch(err => {
|
|
290
|
+
console.error('Failed to copy:', err);
|
|
291
|
+
button.textContent = '✗ Failed';
|
|
292
|
+
setTimeout(() => {
|
|
293
|
+
button.textContent = '📋 Copy';
|
|
294
|
+
}, 2000);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Close modal when clicking outside
|
|
299
|
+
window.onclick = function(event) {
|
|
300
|
+
const modal = document.getElementById('apiModal');
|
|
301
|
+
if (event.target === modal) {
|
|
302
|
+
closeModal();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Close modal with Escape key
|
|
307
|
+
document.addEventListener('keydown', function(event) {
|
|
308
|
+
if (event.key === 'Escape') {
|
|
309
|
+
closeModal();
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
</script>
|
|
313
|
+
|
|
314
|
+
<div class="features-section">
|
|
315
|
+
<h2>✨ Features</h2>
|
|
316
|
+
<div class="features-grid">
|
|
317
|
+
<div class="feature-item">
|
|
318
|
+
<div class="feature-icon">⚡</div>
|
|
319
|
+
<h3>Real-time Monitoring</h3>
|
|
320
|
+
<p>Live updates every 10-30 seconds</p>
|
|
321
|
+
</div>
|
|
322
|
+
<div class="feature-item">
|
|
323
|
+
<div class="feature-icon">📊</div>
|
|
324
|
+
<h3>Interactive Charts</h3>
|
|
325
|
+
<p>Visualize CPU and memory usage</p>
|
|
326
|
+
</div>
|
|
327
|
+
<div class="feature-item">
|
|
328
|
+
<div class="feature-icon">🔔</div>
|
|
329
|
+
<h3>Smart Alerts</h3>
|
|
330
|
+
<p>Email and Slack notifications</p>
|
|
331
|
+
</div>
|
|
332
|
+
<div class="feature-item">
|
|
333
|
+
<div class="feature-icon">💾</div>
|
|
334
|
+
<h3>Error Tracking</h3>
|
|
335
|
+
<p>Comprehensive error logging</p>
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
|
|
341
|
+
<%- include('partials/footer') %>
|
|
@@ -0,0 +1,50 @@
|
|
|
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><%= title %> - Node Monitor</title>
|
|
7
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
8
|
+
<script src="/js/theme.js"></script>
|
|
9
|
+
<% if (includeCharts) { %>
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
|
11
|
+
<% } %>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div class="container">
|
|
15
|
+
<!-- Header -->
|
|
16
|
+
<div class="header">
|
|
17
|
+
<h1><%= headerIcon %> <%= headerTitle %></h1>
|
|
18
|
+
<% if (subtitle) { %>
|
|
19
|
+
<p class="subtitle"><%= subtitle %></p>
|
|
20
|
+
<% } %>
|
|
21
|
+
|
|
22
|
+
<!-- Navigation -->
|
|
23
|
+
<div class="nav-links">
|
|
24
|
+
<a href="/" class="nav-link <%= currentPage === 'home' ? 'active' : '' %>">🏠 Home</a>
|
|
25
|
+
<a href="/monitor/dashboard" class="nav-link <%= currentPage === 'dashboard' ? 'active' : '' %>">📊 Dashboard</a>
|
|
26
|
+
<a href="/health" class="nav-link <%= currentPage === 'health' ? 'active' : '' %>">💚 Health</a>
|
|
27
|
+
<a href="/monitor/metrics" class="nav-link <%= currentPage === 'metrics' ? 'active' : '' %>">📈 Metrics</a>
|
|
28
|
+
<a href="/monitor/status" class="nav-link" target="_blank">📋 API</a>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<!-- Main Content -->
|
|
33
|
+
<div id="mainContent">
|
|
34
|
+
<%- body %>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<!-- Footer -->
|
|
38
|
+
<div class="footer">
|
|
39
|
+
<p>Node Monitor v1.0.0 | Built with ❤️ By Manish Desai</p>
|
|
40
|
+
<p class="timestamp" id="lastUpdate"></p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<script src="/js/main.js"></script>
|
|
45
|
+
<% if (pageScript) { %>
|
|
46
|
+
<script src="/js/<%= pageScript %>"></script>
|
|
47
|
+
<% } %>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
50
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%- include('partials/header') %>
|
|
2
|
+
|
|
3
|
+
<div id="statsContent">
|
|
4
|
+
<div class="loading">
|
|
5
|
+
<div class="spinner"></div>
|
|
6
|
+
<p>Loading metrics data...</p>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div id="chartsContent"></div>
|
|
11
|
+
|
|
12
|
+
<div class="action-buttons">
|
|
13
|
+
<button class="refresh-btn" onclick="loadMetrics()">🔄 Refresh Metrics</button>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<%- include('partials/footer') %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
</div>
|
|
2
|
+
|
|
3
|
+
<!-- Footer -->
|
|
4
|
+
<div class="footer">
|
|
5
|
+
<p>Node Monitor v1.0.0 | Built with ❤️ By Manish Desai</p>
|
|
6
|
+
<p class="timestamp" id="lastUpdate"></p>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<script src="/js/main.js"></script>
|
|
11
|
+
<% if (typeof pageScript !== 'undefined' && pageScript) { %>
|
|
12
|
+
<script src="/js/<%= pageScript %>"></script>
|
|
13
|
+
<% } %>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
16
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
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><%= title %> - Node Monitor</title>
|
|
7
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
8
|
+
<script src="/js/theme.js"></script>
|
|
9
|
+
<% if (typeof includeCharts !== 'undefined' && includeCharts) { %>
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
|
11
|
+
<% } %>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div class="container">
|
|
15
|
+
<!-- Header -->
|
|
16
|
+
<div class="header">
|
|
17
|
+
<h1><%= headerIcon %> <%= headerTitle %></h1>
|
|
18
|
+
<% if (typeof subtitle !== 'undefined' && subtitle) { %>
|
|
19
|
+
<p class="subtitle"><%= subtitle %></p>
|
|
20
|
+
<% } %>
|
|
21
|
+
|
|
22
|
+
<!-- Navigation -->
|
|
23
|
+
<div class="nav-links">
|
|
24
|
+
<a href="/" class="nav-link <%= currentPage === 'home' ? 'active' : '' %>">🏠 Home</a>
|
|
25
|
+
<a href="/monitor/dashboard" class="nav-link <%= currentPage === 'dashboard' ? 'active' : '' %>">📊 Dashboard</a>
|
|
26
|
+
<a href="/health" class="nav-link <%= currentPage === 'health' ? 'active' : '' %>">💚 Health</a>
|
|
27
|
+
<a href="/monitor/metrics" class="nav-link <%= currentPage === 'metrics' ? 'active' : '' %>">📈 Metrics</a>
|
|
28
|
+
<a href="/monitor/status" class="nav-link <%= currentPage === 'status' ? 'active' : '' %>">📋 Status</a>
|
|
29
|
+
<a href="/monitor/error-logs" class="nav-link <%= currentPage === 'error-logs' ? 'active' : '' %>">🔴 Error Logs</a>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<!-- Main Content -->
|
|
34
|
+
<div id="mainContent">
|
|
35
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- Navigation Only Partial (no HTML/HEAD/BODY tags) -->
|
|
2
|
+
<div class="container">
|
|
3
|
+
<!-- Header -->
|
|
4
|
+
<div class="header">
|
|
5
|
+
<h1><%= headerIcon %> <%= headerTitle %></h1>
|
|
6
|
+
<% if (typeof subtitle !== 'undefined' && subtitle) { %>
|
|
7
|
+
<p class="subtitle"><%= subtitle %></p>
|
|
8
|
+
<% } %>
|
|
9
|
+
|
|
10
|
+
<!-- Navigation -->
|
|
11
|
+
<div class="nav-links">
|
|
12
|
+
<a href="/" class="nav-link <%= currentPage === 'home' ? 'active' : '' %>">🏠 Home</a>
|
|
13
|
+
<a href="/monitor/dashboard" class="nav-link <%= currentPage === 'dashboard' ? 'active' : '' %>">📊 Dashboard</a>
|
|
14
|
+
<a href="/health" class="nav-link <%= currentPage === 'health' ? 'active' : '' %>">💚 Health</a>
|
|
15
|
+
<a href="/monitor/metrics" class="nav-link <%= currentPage === 'metrics' ? 'active' : '' %>">📈 Metrics</a>
|
|
16
|
+
<a href="/monitor/status" class="nav-link <%= currentPage === 'status' ? 'active' : '' %>">📋 Status</a>
|
|
17
|
+
<a href="/monitor/error-logs" class="nav-link <%= currentPage === 'error-logs' ? 'active' : '' %>">🔴 Error Logs</a>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<!-- Main Content -->
|
|
22
|
+
<div id="mainContent">
|
|
23
|
+
|