@sera4/essentia 1.1.58 → 1.1.62
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/health/index.js +35 -15
- package/index.js +1 -0
- package/package.json +8 -5
- package/package.tar.gz +0 -0
- package/prompts/index.js +78 -0
package/health/index.js
CHANGED
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import pathHelper from "path";
|
|
4
4
|
import logger from "./health-logger.js";
|
|
5
|
+
import morgan from "morgan";
|
|
5
6
|
|
|
6
|
-
class HealthCheckError extends Error {
|
|
7
|
-
constructor(m) {
|
|
8
|
-
super(m);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
7
|
+
class HealthCheckError extends Error {}
|
|
11
8
|
|
|
12
9
|
/* Health Checking router + controller for use in all of our modules
|
|
13
10
|
* Example use: Place the following code in your routes file
|
|
@@ -36,6 +33,7 @@ class HealthCheck {
|
|
|
36
33
|
this.defaultPathRoute = `health_check\(.*\)?`
|
|
37
34
|
this.suppressLogs = false;
|
|
38
35
|
this.lastCallId = 0; // default start point/integer
|
|
36
|
+
this.pathPrefix = "";
|
|
39
37
|
this.healthChecks = [];
|
|
40
38
|
}
|
|
41
39
|
|
|
@@ -50,7 +48,14 @@ class HealthCheck {
|
|
|
50
48
|
this.healthChecks.push(fcn);
|
|
51
49
|
}
|
|
52
50
|
|
|
51
|
+
setPrefix(prefix) {
|
|
52
|
+
this.pathPrefix = prefix;
|
|
53
|
+
}
|
|
54
|
+
|
|
53
55
|
defaultPath(prefix = "") {
|
|
56
|
+
if (prefix === "") {
|
|
57
|
+
prefix = this.pathPrefix; // maybe setup manually
|
|
58
|
+
}
|
|
54
59
|
return `${prefix}/${this.defaultPathRoute}`
|
|
55
60
|
}
|
|
56
61
|
|
|
@@ -67,6 +72,14 @@ class HealthCheck {
|
|
|
67
72
|
return router
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
suppressHealthCheckLog(app) {
|
|
76
|
+
// Custom morgan skip function to ignore health check logging
|
|
77
|
+
console.log("skip: ", this.defaultPath())
|
|
78
|
+
app.use(morgan('combined', {
|
|
79
|
+
skip: (req) => req.path === defaultPath()
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
|
|
70
83
|
// v2 version of health check, replaced addCheck
|
|
71
84
|
// example:
|
|
72
85
|
// const checkRedisFcn = async () => { await cache.ping().then(() => true) }
|
|
@@ -75,7 +88,7 @@ class HealthCheck {
|
|
|
75
88
|
this.healthChecks.push(config);
|
|
76
89
|
}
|
|
77
90
|
|
|
78
|
-
/* performs health checks and returns 200 if true and 500 if not */
|
|
91
|
+
/* performs health checks and returns 200 if true and 500 if not */
|
|
79
92
|
async checkHealth(req, res) {
|
|
80
93
|
const checkFormat = pathHelper.extname(req.baseUrl);
|
|
81
94
|
|
|
@@ -83,19 +96,27 @@ class HealthCheck {
|
|
|
83
96
|
if (typeof(hc) === "function") {
|
|
84
97
|
try {
|
|
85
98
|
return await hc();
|
|
86
|
-
return { "result": "success", critical: false };
|
|
87
99
|
} catch(e) {
|
|
88
100
|
return { name: "unknown", result: 'fail', status: e.status }
|
|
89
101
|
}
|
|
90
102
|
} else {
|
|
91
103
|
let res = { name: hc.name, critical: hc.critical }
|
|
92
104
|
try {
|
|
93
|
-
await hc.healthFunction();
|
|
94
|
-
|
|
105
|
+
const result = await hc.healthFunction();
|
|
106
|
+
if (typeof(result) === "boolean") {
|
|
107
|
+
if (result === false) {
|
|
108
|
+
res = {"result": "fail", ...res }
|
|
109
|
+
} else {
|
|
110
|
+
res = {"result": "success", ...res }
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
res = {"result": "success", ...res }
|
|
114
|
+
}
|
|
115
|
+
return res;
|
|
95
116
|
} catch(e) {
|
|
96
117
|
const appendStatus = e.status ? ` (${e.status})` : ""
|
|
97
118
|
logger.warn(`${hc.name} service failed${appendStatus}` )
|
|
98
|
-
return { ...res, "result": "fail", status: e.status }
|
|
119
|
+
return { ...res, "result": "fail", status: e.status }
|
|
99
120
|
}
|
|
100
121
|
}
|
|
101
122
|
}));
|
|
@@ -115,7 +136,7 @@ class HealthCheck {
|
|
|
115
136
|
|
|
116
137
|
result.some(e => {
|
|
117
138
|
if (e.result.match(/fail/)) {
|
|
118
|
-
if (e.critical
|
|
139
|
+
if (e.critical === false) {
|
|
119
140
|
nonCriticalFail = true;
|
|
120
141
|
} else {
|
|
121
142
|
criticalFail = true;
|
|
@@ -153,16 +174,15 @@ class HealthCheck {
|
|
|
153
174
|
status_message = "fail"
|
|
154
175
|
} else if ((status === 200) || nonCriticalFail) {
|
|
155
176
|
status_message = "success"
|
|
156
|
-
}
|
|
177
|
+
}
|
|
157
178
|
|
|
158
179
|
res.status(status).send(status_message);
|
|
159
180
|
}
|
|
160
181
|
} catch(error) {
|
|
161
|
-
console.
|
|
182
|
+
console.warn("error: ", error)
|
|
162
183
|
res.status(500).send();
|
|
163
184
|
}
|
|
164
185
|
}
|
|
165
186
|
}
|
|
166
187
|
|
|
167
|
-
|
|
168
|
-
export { HealthCheck };
|
|
188
|
+
export { HealthCheck };
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sera4/essentia",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.62",
|
|
4
4
|
"description": "A library of utilities for Teleporte Web Services",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,21 +20,24 @@
|
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"chai": "^4.3.4",
|
|
22
22
|
"express": "^4.17.1",
|
|
23
|
-
"mocha": "^
|
|
24
|
-
"mocha-junit-reporter": "^
|
|
25
|
-
"node-mocks-http": "^1.
|
|
23
|
+
"mocha": "^11.1.0",
|
|
24
|
+
"mocha-junit-reporter": "^2.2.1",
|
|
25
|
+
"node-mocks-http": "^1.16.2",
|
|
26
26
|
"should": "^13.2.3",
|
|
27
27
|
"sinon": "^5.1.1"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"amqplib": "^0.8.0",
|
|
31
|
+
"argparse": "^2.0.1",
|
|
31
32
|
"async": "^3.2.2",
|
|
32
|
-
"axios": "^1.
|
|
33
|
+
"axios": "^1.7.7",
|
|
33
34
|
"deep-diff": "^1.0.2",
|
|
34
35
|
"diff": "^5.0.0",
|
|
35
36
|
"fast-safe-stringify": "^2.0.7",
|
|
36
37
|
"git-rev": "^0.2.1",
|
|
37
38
|
"lodash": "^4.17.21",
|
|
39
|
+
"morgan": "^1.10.0",
|
|
40
|
+
"prompt": "^1.3.0",
|
|
38
41
|
"url-parse": "^1.5.10",
|
|
39
42
|
"uuid": "^9.0.0",
|
|
40
43
|
"winston": "^3.3.3",
|
package/package.tar.gz
CHANGED
|
Binary file
|
package/prompts/index.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/* Essentia Common Prompt Functions */
|
|
2
|
+
// This file contains common prompt functions that are used in CLI scripts
|
|
3
|
+
// that are run in the each project. These functions are used to
|
|
4
|
+
// prompt the user for input and to wait for the user to press enter
|
|
5
|
+
// before continuing. This is useful for scripts that are run in the
|
|
6
|
+
// command line and need to wait for the user to do something before
|
|
7
|
+
// continuing.
|
|
8
|
+
|
|
9
|
+
import logger from "../logger/s4-logger.js";
|
|
10
|
+
import { ArgumentParser } from 'argparse'
|
|
11
|
+
import prompt from "prompt";
|
|
12
|
+
|
|
13
|
+
// New common argument parser which makes parsing and setting up commandline options easier
|
|
14
|
+
const setupCLIParser = (description) => {
|
|
15
|
+
logger.info(description)
|
|
16
|
+
return new ArgumentParser({ description });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// a common init function which waits for the command prompt to be delivered
|
|
20
|
+
// a common use is for the awaiting of the queues to initialize before running
|
|
21
|
+
const commonCLIInit = async(options) => {
|
|
22
|
+
//add in defaults to options if they have not been specified or object is {}
|
|
23
|
+
options = { asyncFcns: [], extraFcns: [], sleepTime: 1000, ...options };
|
|
24
|
+
|
|
25
|
+
// Sleep for 1 second to allow the prompt to be displayed
|
|
26
|
+
// at the end of bootstrap logs
|
|
27
|
+
await cliSleep(options.sleepTime);
|
|
28
|
+
|
|
29
|
+
options.extraFcns.forEach(fcn => {
|
|
30
|
+
fcn();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
for (const fcn of options.asyncFcns) {
|
|
34
|
+
await fcn();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const promptCLIAsync = async (options) => {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
prompt.start();
|
|
41
|
+
prompt.get(options, (err, res) => {
|
|
42
|
+
if (err) {
|
|
43
|
+
reject(err);
|
|
44
|
+
} else {
|
|
45
|
+
resolve(res);
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// A predefined waitPrompt for use at the end of the scripts that use
|
|
52
|
+
// message queues. Message Queues often take a bit to fire
|
|
53
|
+
const waitCLIPrompt = {
|
|
54
|
+
"Push <enter> when done" : {
|
|
55
|
+
type: "boolean"
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const continueCLIPrompt = {
|
|
60
|
+
"Push <enter> to continue" : {
|
|
61
|
+
type: "boolean"
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const cliSleep = async(ms) => {
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
setTimeout(resolve, ms);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export {
|
|
72
|
+
commonCLIInit,
|
|
73
|
+
continueCLIPrompt,
|
|
74
|
+
promptCLIAsync,
|
|
75
|
+
setupCLIParser,
|
|
76
|
+
cliSleep,
|
|
77
|
+
waitCLIPrompt
|
|
78
|
+
};
|