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,499 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example Express Application with Node Monitor
|
|
3
|
+
* Demonstrates how to integrate the monitoring package
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Load environment variables
|
|
7
|
+
require('dotenv').config();
|
|
8
|
+
|
|
9
|
+
const express = require('express');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const NodeMonitor = require('../src/index');
|
|
12
|
+
|
|
13
|
+
// Initialize the monitor with custom configuration
|
|
14
|
+
const monitor = new NodeMonitor({
|
|
15
|
+
app: {
|
|
16
|
+
name: 'Example Express App',
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
environment: process.env.NODE_ENV || 'development'
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
intervals: {
|
|
22
|
+
health: 30000, // Check health every 30 seconds
|
|
23
|
+
system: 60000, // Check system resources every minute
|
|
24
|
+
database: 60000 // Check database every minute
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
thresholds: {
|
|
28
|
+
cpu: 75, // Alert if CPU > 75%
|
|
29
|
+
memory: 85, // Alert if memory > 85%
|
|
30
|
+
errorRate: 10, // Alert if > 10 errors per minute
|
|
31
|
+
responseTime: 3000, // Alert if response time > 3 seconds
|
|
32
|
+
consecutiveFailures: 2
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
notifications: {
|
|
36
|
+
enabled: true,
|
|
37
|
+
cooldown: 180000, // 3 minutes between alerts
|
|
38
|
+
|
|
39
|
+
email: {
|
|
40
|
+
enabled: true,
|
|
41
|
+
host: 'smtp.gmail.com',
|
|
42
|
+
port: 587,
|
|
43
|
+
secure: false,
|
|
44
|
+
auth: {
|
|
45
|
+
user: 'manish.proses@gmail.com',
|
|
46
|
+
pass: process.env.EMAIL_APP_PASSWORD || 'your-app-password-here'
|
|
47
|
+
},
|
|
48
|
+
from: 'manish.proses@gmail.com',
|
|
49
|
+
recipients: ['manish.proses@gmail.com']
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
slack: {
|
|
53
|
+
enabled: false, // Set to true and configure to enable
|
|
54
|
+
// webhook: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL',
|
|
55
|
+
// channel: '#monitoring'
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
logging: {
|
|
60
|
+
enabled: true,
|
|
61
|
+
level: 'info',
|
|
62
|
+
directory: './logs',
|
|
63
|
+
console: true
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Create Express app
|
|
68
|
+
const app = express();
|
|
69
|
+
const PORT = process.env.PORT || 3001;
|
|
70
|
+
|
|
71
|
+
// ============================================
|
|
72
|
+
// SETUP VIEW ENGINE (EJS)
|
|
73
|
+
// ============================================
|
|
74
|
+
app.set('view engine', 'ejs');
|
|
75
|
+
app.set('views', path.join(__dirname, 'views'));
|
|
76
|
+
|
|
77
|
+
// Serve static files (CSS, JS, images)
|
|
78
|
+
app.use(express.static(path.join(__dirname, 'public')));
|
|
79
|
+
|
|
80
|
+
// Middleware
|
|
81
|
+
app.use(express.json());
|
|
82
|
+
app.use(express.urlencoded({ extended: true }));
|
|
83
|
+
|
|
84
|
+
// Add request logger (optional - logs slow requests)
|
|
85
|
+
app.use(monitor.requestLogger());
|
|
86
|
+
|
|
87
|
+
// ============================================
|
|
88
|
+
// MONITORING ENDPOINTS
|
|
89
|
+
// ============================================
|
|
90
|
+
|
|
91
|
+
// Health check endpoint (HTML or JSON)
|
|
92
|
+
app.get('/health', (req, res) => {
|
|
93
|
+
const acceptsJson = req.headers.accept && req.headers.accept.includes('application/json');
|
|
94
|
+
const isApiRequest = req.query.format === 'json' || acceptsJson;
|
|
95
|
+
|
|
96
|
+
if (!isApiRequest) {
|
|
97
|
+
// Default to HTML for browser requests
|
|
98
|
+
return res.render('health', {
|
|
99
|
+
title: 'Health Check',
|
|
100
|
+
headerIcon: 'š',
|
|
101
|
+
headerTitle: 'Health Check',
|
|
102
|
+
subtitle: 'System health status and monitoring',
|
|
103
|
+
currentPage: 'health',
|
|
104
|
+
includeCharts: false,
|
|
105
|
+
pageScript: 'health.js'
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Return JSON for API requests
|
|
110
|
+
monitor.healthCheckEndpoint()(req, res);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Basic health info
|
|
114
|
+
app.get('/health/info', monitor.healthInfoEndpoint());
|
|
115
|
+
|
|
116
|
+
// Monitoring dashboard (HTML or JSON)
|
|
117
|
+
app.get('/monitor/dashboard', (req, res) => {
|
|
118
|
+
const acceptsJson = req.headers.accept && req.headers.accept.includes('application/json');
|
|
119
|
+
const isApiRequest = req.query.format === 'json' || acceptsJson;
|
|
120
|
+
|
|
121
|
+
if (!isApiRequest) {
|
|
122
|
+
// Default to HTML for browser requests
|
|
123
|
+
return res.render('dashboard', {
|
|
124
|
+
title: 'Dashboard',
|
|
125
|
+
headerIcon: 'š',
|
|
126
|
+
headerTitle: 'Monitoring Dashboard',
|
|
127
|
+
subtitle: 'Real-time application monitoring and analytics',
|
|
128
|
+
currentPage: 'dashboard',
|
|
129
|
+
includeCharts: false,
|
|
130
|
+
pageScript: 'dashboard.js'
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Return JSON for API requests
|
|
135
|
+
monitor.dashboardEndpoint()(req, res);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Get current monitoring status
|
|
139
|
+
// Get status (HTML or JSON)
|
|
140
|
+
app.get('/monitor/status', (req, res) => {
|
|
141
|
+
const acceptsJson = req.headers.accept && req.headers.accept.includes('application/json');
|
|
142
|
+
const isApiRequest = req.query.format === 'json' || acceptsJson;
|
|
143
|
+
|
|
144
|
+
if (!isApiRequest) {
|
|
145
|
+
// Default to HTML for browser requests
|
|
146
|
+
return res.render('status', {
|
|
147
|
+
title: 'API Status',
|
|
148
|
+
headerIcon: 'š',
|
|
149
|
+
headerTitle: 'API Status',
|
|
150
|
+
subtitle: 'Real-time application status and metrics',
|
|
151
|
+
currentPage: 'status'
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Return JSON for API requests
|
|
156
|
+
res.json(monitor.getStatus());
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Get system information
|
|
160
|
+
app.get('/monitor/system', (req, res) => {
|
|
161
|
+
res.json(monitor.getSystemInfo());
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Get metrics history (HTML or JSON)
|
|
165
|
+
app.get('/monitor/metrics', (req, res) => {
|
|
166
|
+
const acceptsJson = req.headers.accept && req.headers.accept.includes('application/json');
|
|
167
|
+
const isApiRequest = req.query.format === 'json' || acceptsJson;
|
|
168
|
+
|
|
169
|
+
if (!isApiRequest) {
|
|
170
|
+
// Default to HTML for browser requests
|
|
171
|
+
return res.render('metrics', {
|
|
172
|
+
title: 'Metrics',
|
|
173
|
+
headerIcon: 'š',
|
|
174
|
+
headerTitle: 'System Metrics',
|
|
175
|
+
subtitle: 'Performance monitoring and analytics',
|
|
176
|
+
currentPage: 'metrics',
|
|
177
|
+
includeCharts: true,
|
|
178
|
+
pageScript: 'metrics.js'
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Return JSON for API requests
|
|
183
|
+
res.json({
|
|
184
|
+
timestamp: new Date().toISOString(),
|
|
185
|
+
history: monitor.getMetricsHistory()
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// ============================================
|
|
190
|
+
// EXAMPLE APPLICATION ROUTES
|
|
191
|
+
// ============================================
|
|
192
|
+
|
|
193
|
+
// Home route
|
|
194
|
+
app.get('/', (req, res) => {
|
|
195
|
+
const acceptsJson = req.headers.accept && req.headers.accept.includes('application/json');
|
|
196
|
+
const isApiRequest = req.query.format === 'json' || acceptsJson;
|
|
197
|
+
|
|
198
|
+
if (!isApiRequest) {
|
|
199
|
+
// Default to HTML for browser requests
|
|
200
|
+
return res.render('home', {
|
|
201
|
+
title: 'Home',
|
|
202
|
+
headerIcon: 'š ',
|
|
203
|
+
headerTitle: 'Node Monitor',
|
|
204
|
+
subtitle: null,
|
|
205
|
+
currentPage: 'home',
|
|
206
|
+
includeCharts: false,
|
|
207
|
+
pageScript: null
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Return JSON for API clients
|
|
212
|
+
res.json({
|
|
213
|
+
message: 'Welcome to Node Monitor Example App',
|
|
214
|
+
endpoints: {
|
|
215
|
+
home: '/',
|
|
216
|
+
health: '/health',
|
|
217
|
+
healthInfo: '/health/info',
|
|
218
|
+
dashboard: '/monitor/dashboard',
|
|
219
|
+
status: '/monitor/status',
|
|
220
|
+
system: '/monitor/system',
|
|
221
|
+
metrics: '/monitor/metrics',
|
|
222
|
+
examples: {
|
|
223
|
+
success: '/api/success',
|
|
224
|
+
error: '/api/error',
|
|
225
|
+
slow: '/api/slow',
|
|
226
|
+
customNotification: '/api/notify'
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// Remove the old inline HTML (keeping this comment for reference)
|
|
233
|
+
/*
|
|
234
|
+
// Old home route with inline HTML - now replaced with EJS
|
|
235
|
+
app.get('/', (req, res) => {
|
|
236
|
+
const acceptsHtml = req.headers.accept && req.headers.accept.includes('text/html');
|
|
237
|
+
|
|
238
|
+
if (acceptsHtml) {
|
|
239
|
+
// Serve HTML landing page
|
|
240
|
+
res.send(`
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
// Success endpoint
|
|
244
|
+
app.get('/api/success', (req, res) => {
|
|
245
|
+
monitor.logInfo('Success endpoint called');
|
|
246
|
+
res.json({ message: 'Success!' });
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Error endpoint (demonstrates error tracking)
|
|
250
|
+
app.get('/api/error', (req, res, next) => {
|
|
251
|
+
const error = NodeMonitor.createError('This is a test error', 500, {
|
|
252
|
+
testData: 'example'
|
|
253
|
+
});
|
|
254
|
+
next(error);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Slow endpoint (demonstrates slow request tracking)
|
|
258
|
+
app.get('/api/slow', monitor.asyncHandler(async (req, res) => {
|
|
259
|
+
// Simulate slow operation
|
|
260
|
+
await new Promise(resolve => setTimeout(resolve, 4000));
|
|
261
|
+
res.json({ message: 'This was a slow request' });
|
|
262
|
+
}));
|
|
263
|
+
|
|
264
|
+
// Test notification endpoint (GET request for easy testing)
|
|
265
|
+
app.get('/api/notify-test', monitor.asyncHandler(async (req, res) => {
|
|
266
|
+
const result = await monitor.notify(
|
|
267
|
+
'info',
|
|
268
|
+
'Test Notification',
|
|
269
|
+
'This is a test email notification from Node Monitor. If you received this, your email configuration is working correctly!',
|
|
270
|
+
{
|
|
271
|
+
testTime: new Date().toISOString(),
|
|
272
|
+
recipient: 'manish.proses@gmail.com',
|
|
273
|
+
status: 'Email configuration is working! ā
'
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
res.json({
|
|
278
|
+
message: 'Test notification sent!',
|
|
279
|
+
result,
|
|
280
|
+
instructions: 'Check your email inbox at manish.proses@gmail.com'
|
|
281
|
+
});
|
|
282
|
+
}));
|
|
283
|
+
|
|
284
|
+
// Custom notification endpoint (POST)
|
|
285
|
+
app.post('/api/notify', monitor.asyncHandler(async (req, res) => {
|
|
286
|
+
const { level, subject, message, details } = req.body;
|
|
287
|
+
|
|
288
|
+
const result = await monitor.notify(
|
|
289
|
+
level || 'info',
|
|
290
|
+
subject || 'Test Notification',
|
|
291
|
+
message || 'This is a test notification',
|
|
292
|
+
details || {}
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
res.json({
|
|
296
|
+
message: 'Notification sent',
|
|
297
|
+
result
|
|
298
|
+
});
|
|
299
|
+
}));
|
|
300
|
+
|
|
301
|
+
// Error logs viewer endpoint
|
|
302
|
+
app.get('/monitor/error-logs', monitor.asyncHandler(async (req, res) => {
|
|
303
|
+
const fs = require('fs');
|
|
304
|
+
const path = require('path');
|
|
305
|
+
|
|
306
|
+
const logsDir = path.join(__dirname, 'logs');
|
|
307
|
+
const { date, format } = req.query;
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
// Ensure logs directory exists
|
|
311
|
+
if (!fs.existsSync(logsDir)) {
|
|
312
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Get list of error log files
|
|
316
|
+
const files = fs.readdirSync(logsDir)
|
|
317
|
+
.filter(f => f.startsWith('error-') && f.endsWith('.log'))
|
|
318
|
+
.sort()
|
|
319
|
+
.reverse();
|
|
320
|
+
|
|
321
|
+
if (format === 'json') {
|
|
322
|
+
// Return list of available log files
|
|
323
|
+
const logFiles = files.map(f => {
|
|
324
|
+
const stats = fs.statSync(path.join(logsDir, f));
|
|
325
|
+
return {
|
|
326
|
+
filename: f,
|
|
327
|
+
date: f.replace('error-', '').replace('.log', ''),
|
|
328
|
+
size: stats.size,
|
|
329
|
+
modified: stats.mtime
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
return res.json({ files: logFiles });
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Render HTML view
|
|
337
|
+
res.render('error-logs', {
|
|
338
|
+
title: 'API Error Logs',
|
|
339
|
+
headerIcon: 'š',
|
|
340
|
+
headerTitle: 'API Error Logs',
|
|
341
|
+
subtitle: 'View and analyze API errors',
|
|
342
|
+
currentPage: 'error-logs',
|
|
343
|
+
files: files.length > 0 ? files : []
|
|
344
|
+
});
|
|
345
|
+
} catch (error) {
|
|
346
|
+
res.status(500).json({ error: error.message });
|
|
347
|
+
}
|
|
348
|
+
}));
|
|
349
|
+
|
|
350
|
+
// Get specific error log file content
|
|
351
|
+
app.get('/monitor/error-logs/:filename', monitor.asyncHandler(async (req, res) => {
|
|
352
|
+
const fs = require('fs');
|
|
353
|
+
const path = require('path');
|
|
354
|
+
const { filename } = req.params;
|
|
355
|
+
const { format, limit = 100 } = req.query;
|
|
356
|
+
|
|
357
|
+
// Security: only allow error log files
|
|
358
|
+
if (!filename.startsWith('error-') || !filename.endsWith('.log')) {
|
|
359
|
+
return res.status(400).json({ error: 'Invalid log file' });
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const logPath = path.join(__dirname, 'logs', filename);
|
|
363
|
+
|
|
364
|
+
if (!fs.existsSync(logPath)) {
|
|
365
|
+
return res.status(404).json({ error: 'Log file not found' });
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
const content = fs.readFileSync(logPath, 'utf8');
|
|
370
|
+
const lines = content.trim().split('\n').filter(line => line.trim());
|
|
371
|
+
|
|
372
|
+
// Parse JSON logs
|
|
373
|
+
const errors = lines
|
|
374
|
+
.map((line, index) => {
|
|
375
|
+
try {
|
|
376
|
+
return JSON.parse(line);
|
|
377
|
+
} catch (e) {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
})
|
|
381
|
+
.filter(e => e !== null)
|
|
382
|
+
.reverse() // Most recent first
|
|
383
|
+
.slice(0, parseInt(limit));
|
|
384
|
+
|
|
385
|
+
if (format === 'json') {
|
|
386
|
+
return res.json({
|
|
387
|
+
filename,
|
|
388
|
+
total: lines.length,
|
|
389
|
+
errors
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Return raw content for download
|
|
394
|
+
res.setHeader('Content-Type', 'application/json');
|
|
395
|
+
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
|
396
|
+
res.send(content);
|
|
397
|
+
} catch (error) {
|
|
398
|
+
res.status(500).json({ error: error.message });
|
|
399
|
+
}
|
|
400
|
+
}));
|
|
401
|
+
|
|
402
|
+
// Async error example
|
|
403
|
+
app.get('/api/async-error', monitor.asyncHandler(async (req, res) => {
|
|
404
|
+
// This error will be caught by asyncHandler
|
|
405
|
+
throw new Error('Async operation failed');
|
|
406
|
+
}));
|
|
407
|
+
|
|
408
|
+
// Database simulation endpoint
|
|
409
|
+
app.get('/api/db-test', monitor.asyncHandler(async (req, res) => {
|
|
410
|
+
// In a real app, you would query your database here
|
|
411
|
+
monitor.logInfo('Database query simulated');
|
|
412
|
+
res.json({ message: 'Database query successful' });
|
|
413
|
+
}));
|
|
414
|
+
|
|
415
|
+
// ============================================
|
|
416
|
+
// CUSTOM HEALTH CHECKS
|
|
417
|
+
// ============================================
|
|
418
|
+
|
|
419
|
+
// Register custom health check
|
|
420
|
+
monitor.registerHealthCheck('api-responsive', async () => {
|
|
421
|
+
// Check if API is responsive
|
|
422
|
+
return true; // Return true if healthy, false if not
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
monitor.registerHealthCheck('external-service', async () => {
|
|
426
|
+
// Example: Check external service availability
|
|
427
|
+
try {
|
|
428
|
+
// const response = await axios.get('https://api.example.com/health');
|
|
429
|
+
// return response.status === 200;
|
|
430
|
+
return true;
|
|
431
|
+
} catch {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
// ============================================
|
|
437
|
+
// DATABASE MONITORING (EXAMPLE)
|
|
438
|
+
// ============================================
|
|
439
|
+
|
|
440
|
+
// Uncomment and configure based on your database
|
|
441
|
+
|
|
442
|
+
// MongoDB/Mongoose example:
|
|
443
|
+
// const mongoose = require('mongoose');
|
|
444
|
+
// mongoose.connect('mongodb://localhost:27017/myapp');
|
|
445
|
+
// monitor.registerDatabase('mongodb', 'mongoose', mongoose.connection);
|
|
446
|
+
|
|
447
|
+
// PostgreSQL example:
|
|
448
|
+
// const { Pool } = require('pg');
|
|
449
|
+
// const pgPool = new Pool({ connectionString: 'postgresql://...' });
|
|
450
|
+
// monitor.registerDatabase('postgres', 'postgresql', pgPool);
|
|
451
|
+
|
|
452
|
+
// MySQL example:
|
|
453
|
+
// const mysql = require('mysql2/promise');
|
|
454
|
+
// const mysqlPool = mysql.createPool({ host: 'localhost', user: 'root', database: 'myapp' });
|
|
455
|
+
// monitor.registerDatabase('mysql', 'mysql', mysqlPool);
|
|
456
|
+
|
|
457
|
+
// Redis example:
|
|
458
|
+
// const Redis = require('ioredis');
|
|
459
|
+
// const redis = new Redis();
|
|
460
|
+
// monitor.registerDatabase('redis', 'redis', redis);
|
|
461
|
+
|
|
462
|
+
// ============================================
|
|
463
|
+
// ERROR HANDLING
|
|
464
|
+
// ============================================
|
|
465
|
+
|
|
466
|
+
// 404 handler (must be after all routes)
|
|
467
|
+
app.use(monitor.notFoundHandler());
|
|
468
|
+
|
|
469
|
+
// Error handler (must be last)
|
|
470
|
+
app.use(monitor.errorMiddleware());
|
|
471
|
+
|
|
472
|
+
// ============================================
|
|
473
|
+
// START SERVER
|
|
474
|
+
// ============================================
|
|
475
|
+
|
|
476
|
+
const server = app.listen(PORT, () => {
|
|
477
|
+
console.log(`\nš Server running on http://localhost:${PORT}`);
|
|
478
|
+
console.log(`š Health check: http://localhost:${PORT}/health`);
|
|
479
|
+
console.log(`š Dashboard: http://localhost:${PORT}/monitor/dashboard`);
|
|
480
|
+
console.log(`\nā
Node Monitor is active and monitoring your application\n`);
|
|
481
|
+
|
|
482
|
+
// Start monitoring services
|
|
483
|
+
monitor.start();
|
|
484
|
+
|
|
485
|
+
// Setup graceful shutdown
|
|
486
|
+
monitor.setupGracefulShutdown(server);
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Handle server errors
|
|
490
|
+
server.on('error', (error) => {
|
|
491
|
+
monitor.logError('server_error', 'Server error occurred', {
|
|
492
|
+
error: error.message,
|
|
493
|
+
code: error.code
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// Export for testing
|
|
498
|
+
module.exports = { app, monitor, server };
|
|
499
|
+
|