express-watchdog 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.
Files changed (3) hide show
  1. package/README.md +77 -0
  2. package/index.js +165 -0
  3. package/package.json +24 -0
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # express-watchdog
2
+
3
+ A lightweight, zero-dashboard monitoring helper for Express applications. Keep an eye on your APIs and get alerted when things go slow or the server crashes—all without any complex setup!
4
+
5
+ ## Features
6
+ - **Auto-pilot Monitoring:** Automatically detects slow API responses.
7
+ - **Crash Protection:** Listens for process-level errors and unhandled rejections.
8
+ - **Customizable Actions:** Attach your own logic (logging, Slack, Webhooks) when alerts trigger.
9
+ - **Built-in Emailing:** Seamlessly send Gmail alerts to you and your team (CC supported).
10
+ - **Clear Reports:** Beautifully structured `WHERE–WHAT–WHEN` formats.
11
+ - **Safe & Minimal:** Zero impact on your app's performance and minimal dependencies.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install express-watchdog
17
+ ```
18
+
19
+ ## Basic Usage
20
+
21
+ Getting started is as simple as adding a few lines to your Express app:
22
+
23
+ ```js
24
+ const express = require("express");
25
+ const monitor = require("express-watchdog");
26
+
27
+ const app = express();
28
+
29
+ monitor(app, {
30
+ slowThresholdMs: 2000,
31
+ alertEmail: process.env.ALERT_EMAIL,
32
+ ccEmail: process.env.CC_EMAIL,
33
+ appPassword: process.env.EMAIL_APP_PASSWORD
34
+ });
35
+
36
+ app.listen(3000);
37
+ ```
38
+
39
+ ## Custom Functions (Powerful & Flexible!)
40
+
41
+ Want to send alerts to Slack, log to a database, or trigger a webhook? You can easily attach your own handlers!
42
+
43
+ When you provide `onSlow` or `onCrash`, **express-watchdog** will call your function instead of sending the default email.
44
+
45
+ ```js
46
+ monitor(app, {
47
+ slowThresholdMs: 2000,
48
+ // Your custom logic here!
49
+ onSlow: async ({ where, what, when, path, duration }) => {
50
+ console.log(`Slow API detected at ${path}! Took ${duration}ms.`);
51
+ // Add your Slack integration or database logging here
52
+ },
53
+ onCrash: async ({ where, what, when, message, stack }) => {
54
+ console.error(`Critical Error: ${message}`);
55
+ // Handle the crash gracefully or notify your dev team
56
+ }
57
+ });
58
+ ```
59
+
60
+ ## Email Configuration (Optional)
61
+ If you don't provide custom handlers, the watchdog defaults to sending emails via Gmail.
62
+
63
+ Recommended Environment Variables:
64
+ ```env
65
+ ALERT_EMAIL=yourgmail@gmail.com
66
+ CC_EMAIL=team@example.com
67
+ EMAIL_APP_PASSWORD=your-app-password
68
+ ```
69
+
70
+ ## How It Works
71
+ 1. **Performance Tracking:** Wraps Express requests to measure exactly how long they take.
72
+ 2. **Process Monitoring:** Hooks into `uncaughtException` and `unhandledRejection`.
73
+ 3. **Smart Alerting:** Triggers your custom functions or sends a detailed email with full context.
74
+
75
+ ## License
76
+ ISC
77
+
package/index.js ADDED
@@ -0,0 +1,165 @@
1
+ const nodemailer = require("nodemailer");
2
+
3
+ /**
4
+ * Monitors an Express application for slow APIs and server crashes.
5
+ *
6
+ * @param {import('express').Application} app - The Express application instance.
7
+ * @param {Object} options - Configuration options.
8
+ * @param {number} [options.slowThresholdMs=2000] - Threshold for slow API detection in milliseconds.
9
+ * @param {string} options.alertEmail - Sender email address (Gmail).
10
+ * @param {string} [options.ccEmail] - CC email address.
11
+ * @param {string} options.appPassword - Gmail App Password for authentication.
12
+ * @param {Function} [options.onSlow] - Custom handler for slow API alerts.
13
+ * @param {Function} [options.onCrash] - Custom handler for crash alerts.
14
+ */
15
+ module.exports = function monitor(app, options = {}) {
16
+ const {
17
+ slowThresholdMs = 2000,
18
+ alertEmail,
19
+ ccEmail,
20
+ appPassword,
21
+ onSlow,
22
+ onCrash
23
+ } = options;
24
+
25
+ // --- Utility: Send Email ---
26
+ const sendEmail = async (subject, body) => {
27
+ try {
28
+ if (!alertEmail || !appPassword) {
29
+ console.warn("[express-watchdog] Missing alertEmail or appPassword. Default email alert skipped.");
30
+ return;
31
+ }
32
+
33
+ const transporter = nodemailer.createTransport({
34
+ service: "gmail",
35
+ auth: {
36
+ user: alertEmail,
37
+ pass: appPassword
38
+ }
39
+ });
40
+
41
+ const mailOptions = {
42
+ from: alertEmail,
43
+ to: alertEmail,
44
+ cc: ccEmail,
45
+ subject: `[express-watchdog] Alert: ${subject}`,
46
+ text: body
47
+ };
48
+
49
+ await transporter.sendMail(mailOptions);
50
+ } catch (error) {
51
+ console.error("[express-watchdog] Failed to send email alert:", error.message);
52
+ }
53
+ };
54
+
55
+ // --- 1. Detect Slow APIs Middleware ---
56
+ app.use((req, res, next) => {
57
+ try {
58
+ const start = Date.now();
59
+
60
+ // Listen for the response finish event
61
+ res.on("finish", async () => {
62
+ const duration = Date.now() - start;
63
+
64
+ if (duration > slowThresholdMs) {
65
+ const timestamp = new Date().toISOString();
66
+ const payload = {
67
+ path: req.path,
68
+ method: req.method,
69
+ duration,
70
+ timestamp,
71
+ where: req.path,
72
+ what: "Slow API Response",
73
+ when: timestamp
74
+ };
75
+
76
+ if (typeof onSlow === "function") {
77
+ try {
78
+ await onSlow(payload);
79
+ } catch (err) {
80
+ console.error("[express-watchdog] Error in custom onSlow handler:", err.message);
81
+ }
82
+ } else {
83
+ const body = `
84
+ WHERE:
85
+ ${payload.where}
86
+
87
+ WHAT:
88
+ ${payload.what}
89
+
90
+ WHEN:
91
+ ${payload.timestamp}
92
+
93
+ DETAILS:
94
+ - Path (if API): ${payload.path}
95
+ - Method (if API): ${payload.method}
96
+ - Duration (if slow API): ${payload.duration} ms
97
+ `;
98
+ await sendEmail(payload.what, body.trim());
99
+ }
100
+ }
101
+ });
102
+ } catch (error) {
103
+ console.error("[express-watchdog] Error in slow API middleware:", error.message);
104
+ }
105
+ next();
106
+ });
107
+
108
+ // --- 2. Detect Server Crash ---
109
+ const handleCrash = async (error) => {
110
+ try {
111
+ const timestamp = new Date().toISOString();
112
+ const payload = {
113
+ message: error.message || "Unknown error",
114
+ stack: error.stack || "No stack trace available",
115
+ timestamp,
116
+ where: "Node.js Process",
117
+ what: "Server Crash / Unhandled Error",
118
+ when: timestamp
119
+ };
120
+
121
+ if (typeof onCrash === "function") {
122
+ try {
123
+ await onCrash(payload);
124
+ } catch (err) {
125
+ console.error("[express-watchdog] Error in custom onCrash handler:", err.message);
126
+ }
127
+ } else {
128
+ const body = `
129
+ WHERE:
130
+ ${payload.where}
131
+
132
+ WHAT:
133
+ ${payload.what}
134
+
135
+ WHEN:
136
+ ${payload.timestamp}
137
+
138
+ DETAILS:
139
+ - Error Message (if crash): ${payload.message}
140
+ - Stack Trace (if crash):
141
+ ${payload.stack}
142
+ `;
143
+ await sendEmail(payload.what, body.trim());
144
+ }
145
+ } catch (err) {
146
+ console.error("[express-watchdog] Error in crash handler:", err.message);
147
+ }
148
+
149
+ // Since it's a crash, we might want to log it and let the process die
150
+ // or keep it alive if the user handles it.
151
+ // Usually, uncaughtException should lead to process exit after logging.
152
+ // However, the requirement doesn't explicitly say to exit.
153
+ };
154
+
155
+ process.on("uncaughtException", async (error) => {
156
+ await handleCrash(error);
157
+ // Standard practice is to exit after logging uncaught exception
158
+ // process.exit(1);
159
+ });
160
+
161
+ process.on("unhandledRejection", async (reason) => {
162
+ const error = reason instanceof Error ? reason : new Error(String(reason));
163
+ await handleCrash(error);
164
+ });
165
+ };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "express-watchdog",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight, zero-dashboard monitoring helper for Express applications that detects slow APIs and server crashes.",
5
+ "main": "index.js",
6
+ "keywords": [
7
+ "express",
8
+ "monitoring",
9
+ "alerts",
10
+ "watchdog",
11
+ "performance"
12
+ ],
13
+ "author": "Fayfay",
14
+ "license": "ISC",
15
+ "files": [
16
+ "index.js",
17
+ "README.md",
18
+ "package.json"
19
+ ],
20
+ "dependencies": {
21
+ "express": "^5.2.1",
22
+ "nodemailer": "^8.0.1"
23
+ }
24
+ }