@saber-usa/node-common 1.7.4 → 1.7.6
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 +41 -41
- package/package.json +51 -51
- package/src/LaunchNominalClass.js +0 -2
- package/src/astro.js +97 -1
- package/src/checkNetwork.cjs +20 -20
- package/src/constants.js +5 -0
- package/src/loggerFactory.cjs +98 -98
package/README.md
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
# Saber Common node functions
|
|
2
|
-
|
|
3
|
-
The contains common node functions used across saber applications
|
|
4
|
-
|
|
5
|
-
## Logger
|
|
6
|
-
|
|
7
|
-
The logger component is a standard logger based on [winston](https://github.com/winstonjs/winston). The logger factory
|
|
8
|
-
creates a default console logger for errors along with exception/rejection catching. By setting the `CONSOLE_LOG`
|
|
9
|
-
variable to `true` will turn on the console logger for local development. The log level is configured by the `LOG_LEVEL`
|
|
10
|
-
environment variable to one of the following levels: `emerg`, `alert`, `crit`, `error`, `warning`, `warn`, `notice`,
|
|
11
|
-
`info`, `debug` (default level is `error`). The reason using an environment variable for the level is useful when
|
|
12
|
-
deployed to the server. Changing the environment variable is easier than setting a new flag in the script execution.
|
|
13
|
-
|
|
14
|
-
### Usage
|
|
15
|
-
|
|
16
|
-
To create a new logger, just pass in options to the factory:
|
|
17
|
-
|
|
18
|
-
```javascript
|
|
19
|
-
const logger = loggerFactory(opts);
|
|
20
|
-
|
|
21
|
-
logger.debug("This is a debug message");
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
For further usage, consult [winston](https://github.com/winstonjs/winston)
|
|
25
|
-
|
|
26
|
-
### Options
|
|
27
|
-
|
|
28
|
-
- `nameSpace` help distinguish where the logger message comes from.
|
|
29
|
-
- `additionalData` Data to include with each message
|
|
30
|
-
- `level` overwrite the `LOG_LEVEL` environment level
|
|
31
|
-
|
|
32
|
-
## Transformer
|
|
33
|
-
|
|
34
|
-
A transformer for object keys is provided. This will take an object and transform the keys using a function.
|
|
35
|
-
|
|
36
|
-
## Publishing changes
|
|
37
|
-
|
|
38
|
-
1. Change the version in package.json
|
|
39
|
-
2. Run `npm publish && npm install`
|
|
40
|
-
3. Enable GPG in GIT: `git config --global commit.gpgsign true`
|
|
41
|
-
4. Run `gpg --list-keys` to get your <id>
|
|
1
|
+
# Saber Common node functions
|
|
2
|
+
|
|
3
|
+
The contains common node functions used across saber applications
|
|
4
|
+
|
|
5
|
+
## Logger
|
|
6
|
+
|
|
7
|
+
The logger component is a standard logger based on [winston](https://github.com/winstonjs/winston). The logger factory
|
|
8
|
+
creates a default console logger for errors along with exception/rejection catching. By setting the `CONSOLE_LOG`
|
|
9
|
+
variable to `true` will turn on the console logger for local development. The log level is configured by the `LOG_LEVEL`
|
|
10
|
+
environment variable to one of the following levels: `emerg`, `alert`, `crit`, `error`, `warning`, `warn`, `notice`,
|
|
11
|
+
`info`, `debug` (default level is `error`). The reason using an environment variable for the level is useful when
|
|
12
|
+
deployed to the server. Changing the environment variable is easier than setting a new flag in the script execution.
|
|
13
|
+
|
|
14
|
+
### Usage
|
|
15
|
+
|
|
16
|
+
To create a new logger, just pass in options to the factory:
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
const logger = loggerFactory(opts);
|
|
20
|
+
|
|
21
|
+
logger.debug("This is a debug message");
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For further usage, consult [winston](https://github.com/winstonjs/winston)
|
|
25
|
+
|
|
26
|
+
### Options
|
|
27
|
+
|
|
28
|
+
- `nameSpace` help distinguish where the logger message comes from.
|
|
29
|
+
- `additionalData` Data to include with each message
|
|
30
|
+
- `level` overwrite the `LOG_LEVEL` environment level
|
|
31
|
+
|
|
32
|
+
## Transformer
|
|
33
|
+
|
|
34
|
+
A transformer for object keys is provided. This will take an object and transform the keys using a function.
|
|
35
|
+
|
|
36
|
+
## Publishing changes
|
|
37
|
+
|
|
38
|
+
1. Change the version in package.json
|
|
39
|
+
2. Run `npm publish && npm install`
|
|
40
|
+
3. Enable GPG in GIT: `git config --global commit.gpgsign true`
|
|
41
|
+
4. Run `gpg --list-keys` to get your <id>
|
|
42
42
|
5. Tell the GIT to use your key `git config user.signingkey <id>`
|
package/package.json
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@saber-usa/node-common",
|
|
3
|
-
"version": "1.7.
|
|
4
|
-
"description": "Common node functions for Saber",
|
|
5
|
-
"main": "src/index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"lint": "eslint . --ext js",
|
|
9
|
-
"lint:fix": "eslint . --ext js --fix",
|
|
10
|
-
"test": "jest --no-coverage --silent",
|
|
11
|
-
"test:unit": "jest --coverage --runInBand --no-watch",
|
|
12
|
-
"sonar": "node --experimental-vm-modules sonar-project.js"
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"src/**/*"
|
|
16
|
-
],
|
|
17
|
-
"author": "Saber USA",
|
|
18
|
-
"license": "ISC",
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"@aws-sdk/client-s3": "^3.666.0",
|
|
21
|
-
"date-fns": "^4.1.0",
|
|
22
|
-
"lodash": "4.17.21",
|
|
23
|
-
"mathjs": "^14.7.0",
|
|
24
|
-
"pious-squid": "^2.3.0",
|
|
25
|
-
"plotly": "^1.0.6",
|
|
26
|
-
"satellite.js": "^6.0.1",
|
|
27
|
-
"solar-calculator": "^0.3.0",
|
|
28
|
-
"three": "^0.178.0",
|
|
29
|
-
"winston": "3.3.3"
|
|
30
|
-
},
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"@babel/core": "7.16.0",
|
|
33
|
-
"@babel/eslint-parser": "7.16.3",
|
|
34
|
-
"@babel/plugin-transform-modules-commonjs": "7.16.0",
|
|
35
|
-
"@jest/globals": "27.4.4",
|
|
36
|
-
"eslint-config-google": "0.14.0",
|
|
37
|
-
"eslint-plugin-jest": "25.3.0",
|
|
38
|
-
"jest": "29.7.0",
|
|
39
|
-
"jest-diff": "29.7.0",
|
|
40
|
-
"nodemon": "3.1.4",
|
|
41
|
-
"sonarqube-scanner": "3.0.1"
|
|
42
|
-
},
|
|
43
|
-
"overrides": {
|
|
44
|
-
"braces": "3.0.3"
|
|
45
|
-
},
|
|
46
|
-
"babel": {
|
|
47
|
-
"plugins": [
|
|
48
|
-
"@babel/plugin-transform-modules-commonjs"
|
|
49
|
-
]
|
|
50
|
-
}
|
|
51
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@saber-usa/node-common",
|
|
3
|
+
"version": "1.7.6",
|
|
4
|
+
"description": "Common node functions for Saber",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"lint": "eslint . --ext js",
|
|
9
|
+
"lint:fix": "eslint . --ext js --fix",
|
|
10
|
+
"test": "jest --no-coverage --silent",
|
|
11
|
+
"test:unit": "jest --coverage --runInBand --no-watch",
|
|
12
|
+
"sonar": "node --experimental-vm-modules sonar-project.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"src/**/*"
|
|
16
|
+
],
|
|
17
|
+
"author": "Saber USA",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@aws-sdk/client-s3": "^3.666.0",
|
|
21
|
+
"date-fns": "^4.1.0",
|
|
22
|
+
"lodash": "4.17.21",
|
|
23
|
+
"mathjs": "^14.7.0",
|
|
24
|
+
"pious-squid": "^2.3.0",
|
|
25
|
+
"plotly": "^1.0.6",
|
|
26
|
+
"satellite.js": "^6.0.1",
|
|
27
|
+
"solar-calculator": "^0.3.0",
|
|
28
|
+
"three": "^0.178.0",
|
|
29
|
+
"winston": "3.3.3"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@babel/core": "7.16.0",
|
|
33
|
+
"@babel/eslint-parser": "7.16.3",
|
|
34
|
+
"@babel/plugin-transform-modules-commonjs": "7.16.0",
|
|
35
|
+
"@jest/globals": "27.4.4",
|
|
36
|
+
"eslint-config-google": "0.14.0",
|
|
37
|
+
"eslint-plugin-jest": "25.3.0",
|
|
38
|
+
"jest": "29.7.0",
|
|
39
|
+
"jest-diff": "29.7.0",
|
|
40
|
+
"nodemon": "3.1.4",
|
|
41
|
+
"sonarqube-scanner": "3.0.1"
|
|
42
|
+
},
|
|
43
|
+
"overrides": {
|
|
44
|
+
"braces": "3.0.3"
|
|
45
|
+
},
|
|
46
|
+
"babel": {
|
|
47
|
+
"plugins": [
|
|
48
|
+
"@babel/plugin-transform-modules-commonjs"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/astro.js
CHANGED
|
@@ -42,7 +42,8 @@ import {DEG2RAD,
|
|
|
42
42
|
WGS72_EARTH_EQUATORIAL_RADIUS_KM,
|
|
43
43
|
WGS84_EARTH_EQUATORIAL_RADIUS_KM,
|
|
44
44
|
MILLIS_PER_DAY,
|
|
45
|
-
GEO_ALTITUDE_KM
|
|
45
|
+
GEO_ALTITUDE_KM,
|
|
46
|
+
ERROR_CODES} from "./constants.js";
|
|
46
47
|
|
|
47
48
|
// Solar Terminator
|
|
48
49
|
// Returns sun latitude and longitude as -180/180
|
|
@@ -74,6 +75,98 @@ const checkTle = (line1, line2) => {
|
|
|
74
75
|
}
|
|
75
76
|
};
|
|
76
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Validates the output of the satellite.js propagate function.
|
|
80
|
+
* The satellite.js propagate function returns a object with the following properties:
|
|
81
|
+
* - position: {x: number, y: number, z: number}
|
|
82
|
+
* - velocity: {x: number, y: number, z: number}
|
|
83
|
+
* - meanElements: {am: number, em: number, im: number, Om: number, om: number, nm: number, mm: number}
|
|
84
|
+
*
|
|
85
|
+
* When propgation fails, the output is null. However, there are cases where the output is not null, but the position and velocity are NaN.
|
|
86
|
+
* This happens when the input satrec is invalid or malformed due to a bad TLE, in some way. This is rare, and hard to reproduce.
|
|
87
|
+
*
|
|
88
|
+
* This function takes into account those rare cases as part of the validation.
|
|
89
|
+
*
|
|
90
|
+
* @param {Object} out The output of the satellite.js propagate function.
|
|
91
|
+
* @return {boolean} true if the propagation output is valid, false otherwise
|
|
92
|
+
*/
|
|
93
|
+
const isPropagateValid = (out) => {
|
|
94
|
+
if (out === null || out === undefined) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (out.position) {
|
|
99
|
+
const pos = out.position;
|
|
100
|
+
if (pos.x === null || pos.x === undefined || Number.isNaN(pos.x)
|
|
101
|
+
|| pos.y === null || pos.y === undefined || Number.isNaN(pos.y)
|
|
102
|
+
|| pos.z === null || pos.z === undefined || Number.isNaN(pos.z)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (out.velocity) {
|
|
108
|
+
const vel = out.velocity;
|
|
109
|
+
if (vel.x === null || vel.x === undefined || Number.isNaN(vel.x)
|
|
110
|
+
|| vel.y === null || vel.y === undefined || Number.isNaN(vel.y)
|
|
111
|
+
|| vel.z === null || vel.z === undefined || Number.isNaN(vel.z)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return true;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/** A function that attempts to propagate a satellite record to a given time, and returns a standardized output object.
|
|
120
|
+
*
|
|
121
|
+
* @param {Object} satrec The satellite record from satellite.js
|
|
122
|
+
* @param {Date} time The time to propagate the satellite to
|
|
123
|
+
* @return {Object} An object with the following properties:
|
|
124
|
+
* - ok: 0 or 1
|
|
125
|
+
* - err: null or an error message
|
|
126
|
+
* - out: null or the output of the satellite.js propagate function
|
|
127
|
+
*/
|
|
128
|
+
const tryPropagateSatrec = (satrec, time) => {
|
|
129
|
+
// Validate time
|
|
130
|
+
if (!time || !(time instanceof Date)) {
|
|
131
|
+
return {
|
|
132
|
+
ok: 0,
|
|
133
|
+
err: ERROR_CODES.INVALID_TIME_INPUT,
|
|
134
|
+
out: null,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Validate satrec
|
|
138
|
+
if (!satrec) {
|
|
139
|
+
return {
|
|
140
|
+
ok: 0,
|
|
141
|
+
err: ERROR_CODES.INVALID_SATELLITE_RECORD,
|
|
142
|
+
out: null,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Propagate
|
|
146
|
+
try {
|
|
147
|
+
const out = propagate(satrec, time);
|
|
148
|
+
// Validate propagate output
|
|
149
|
+
if (!isPropagateValid(out)) {
|
|
150
|
+
return {
|
|
151
|
+
ok: 0,
|
|
152
|
+
err: ERROR_CODES.INVALID_PROPAGATE_OUTPUT + `: ${satrec.error}`,
|
|
153
|
+
out: null,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
ok: 1,
|
|
158
|
+
err: null,
|
|
159
|
+
out: out,
|
|
160
|
+
};
|
|
161
|
+
} catch (e) {
|
|
162
|
+
return {
|
|
163
|
+
ok: 0,
|
|
164
|
+
err: ERROR_CODES.INVALID_PROPAGATE_OUTPUT + `: ${e.message}`,
|
|
165
|
+
out: null,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
77
170
|
/**
|
|
78
171
|
* Calculates the semi-major axis in kilometers from a satellite record.
|
|
79
172
|
* @param {Object} satrec The satellite record from satellite.js
|
|
@@ -1629,6 +1722,7 @@ const getLeoRpoData = (line1, line2, sats, startTime, endTime) => {
|
|
|
1629
1722
|
inclination: s.Inclination,
|
|
1630
1723
|
raan: s.Raan,
|
|
1631
1724
|
source: s.Source,
|
|
1725
|
+
datamode: s.DataMode,
|
|
1632
1726
|
sma: s.SemiMajorAxis,
|
|
1633
1727
|
country: s.CountryId,
|
|
1634
1728
|
flag: s.Flag,
|
|
@@ -1719,6 +1813,7 @@ const getGeoRpoData = (line1, line2, sats, startTime, endTime, lonTime) => {
|
|
|
1719
1813
|
satNo: s.SatNo,
|
|
1720
1814
|
source: s.Source,
|
|
1721
1815
|
country: s.CountryId,
|
|
1816
|
+
datamode: s.DataMode,
|
|
1722
1817
|
flag: s.Flag,
|
|
1723
1818
|
poca: 9999999999,
|
|
1724
1819
|
toca: "",
|
|
@@ -3207,6 +3302,7 @@ export {REGIMES,
|
|
|
3207
3302
|
getRaanDetails,
|
|
3208
3303
|
isSatInShadow,
|
|
3209
3304
|
calculateGeoCrossingTimes,
|
|
3305
|
+
tryPropagateSatrec,
|
|
3210
3306
|
};
|
|
3211
3307
|
export const raDecToGeodetic = RaDecToGeodetic;
|
|
3212
3308
|
export const getResiduals = GetResiduals;
|
package/src/checkNetwork.cjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
const _ = require("lodash");
|
|
2
|
-
const {resolve4} = require("dns").promises;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const checkRecord = (hostName) => resolve4(hostName).
|
|
6
|
-
then((addresss) => !_.isEmpty(addresss)).
|
|
7
|
-
catch(_.stubFalse);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
module.exports.checkRecord = checkRecord;
|
|
11
|
-
module.exports.checkNetwork = (domains) => Promise.all(
|
|
12
|
-
_.map(
|
|
13
|
-
domains,
|
|
14
|
-
(hostName) => checkRecord(hostName).
|
|
15
|
-
then((found) => found
|
|
16
|
-
? hostName
|
|
17
|
-
: null,
|
|
18
|
-
),
|
|
19
|
-
),
|
|
20
|
-
).then((resolved) => _.flow(_.compact, _.first)(resolved) || null);
|
|
1
|
+
const _ = require("lodash");
|
|
2
|
+
const {resolve4} = require("dns").promises;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const checkRecord = (hostName) => resolve4(hostName).
|
|
6
|
+
then((addresss) => !_.isEmpty(addresss)).
|
|
7
|
+
catch(_.stubFalse);
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module.exports.checkRecord = checkRecord;
|
|
11
|
+
module.exports.checkNetwork = (domains) => Promise.all(
|
|
12
|
+
_.map(
|
|
13
|
+
domains,
|
|
14
|
+
(hostName) => checkRecord(hostName).
|
|
15
|
+
then((found) => found
|
|
16
|
+
? hostName
|
|
17
|
+
: null,
|
|
18
|
+
),
|
|
19
|
+
),
|
|
20
|
+
).then((resolved) => _.flow(_.compact, _.first)(resolved) || null);
|
package/src/constants.js
CHANGED
package/src/loggerFactory.cjs
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
const winston = require("winston");
|
|
2
|
-
const {
|
|
3
|
-
createLogger,
|
|
4
|
-
format,
|
|
5
|
-
transports,
|
|
6
|
-
} = winston;
|
|
7
|
-
const cj = (data) => Object.keys(data).length > 0
|
|
8
|
-
? JSON.stringify(data, null, 2)
|
|
9
|
-
: null;
|
|
10
|
-
|
|
11
|
-
const isTest = process.env.NODE_ENV === "test";
|
|
12
|
-
|
|
13
|
-
const defaultLogger = new transports.Console({
|
|
14
|
-
silent: isTest,
|
|
15
|
-
level: "warn",
|
|
16
|
-
format: format.errors({stack: true}),
|
|
17
|
-
timestamp: true,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const errorLogger = new transports.Console({
|
|
21
|
-
silent: isTest,
|
|
22
|
-
format: format.errors({stack: true}),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Creates a logger
|
|
27
|
-
*
|
|
28
|
-
* @param {String} nameSpace Namespace for the logger
|
|
29
|
-
* @param {Object} additionalData additional data to include with logging
|
|
30
|
-
* @param {string} level Default logging level to set (overwrites environment setting)
|
|
31
|
-
* @return {winston.Logger}
|
|
32
|
-
*/
|
|
33
|
-
module.exports.loggerFactory = ({
|
|
34
|
-
nameSpace = "saber",
|
|
35
|
-
additionalData = {},
|
|
36
|
-
level,
|
|
37
|
-
} = {}) => {
|
|
38
|
-
const logLevel = process.env.LOG_LEVEL || "warn";
|
|
39
|
-
const isConsole = !!(process.env.CONSOLE_LOG);
|
|
40
|
-
|
|
41
|
-
const loggerTransport = isConsole
|
|
42
|
-
? new transports.Console({
|
|
43
|
-
defaultMeta: additionalData,
|
|
44
|
-
level: level || logLevel,
|
|
45
|
-
format: format.combine(
|
|
46
|
-
format.errors({stack: true}),
|
|
47
|
-
format.cli(),
|
|
48
|
-
// eslint-disable-next-line max-len
|
|
49
|
-
format.printf(({
|
|
50
|
-
level,
|
|
51
|
-
message,
|
|
52
|
-
nameSpace,
|
|
53
|
-
stack,
|
|
54
|
-
...rest
|
|
55
|
-
}) =>
|
|
56
|
-
[
|
|
57
|
-
level,
|
|
58
|
-
`[${nameSpace}]`,
|
|
59
|
-
":",
|
|
60
|
-
message,
|
|
61
|
-
stack,
|
|
62
|
-
cj(rest),
|
|
63
|
-
].filter((value) => !!value)
|
|
64
|
-
.join(" "),
|
|
65
|
-
),
|
|
66
|
-
),
|
|
67
|
-
})
|
|
68
|
-
: defaultLogger;
|
|
69
|
-
|
|
70
|
-
const config = {
|
|
71
|
-
levels: {
|
|
72
|
-
// RFC5424
|
|
73
|
-
emerg: 0,
|
|
74
|
-
alert: 1,
|
|
75
|
-
crit: 2,
|
|
76
|
-
error: 3,
|
|
77
|
-
warning: 4,
|
|
78
|
-
notice: 5,
|
|
79
|
-
info: 6,
|
|
80
|
-
debug: 7,
|
|
81
|
-
// npm levels
|
|
82
|
-
warn: 4,
|
|
83
|
-
verbose: 6,
|
|
84
|
-
silly: 8,
|
|
85
|
-
},
|
|
86
|
-
exitOnError: false,
|
|
87
|
-
transports: [loggerTransport],
|
|
88
|
-
// Console logger from above will log errors
|
|
89
|
-
exceptionHandlers: !isConsole ? [errorLogger] : [],
|
|
90
|
-
rejectionHandlers: !isConsole ? [errorLogger] : [],
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
return createLogger(config)
|
|
94
|
-
.child({
|
|
95
|
-
...additionalData,
|
|
96
|
-
nameSpace: nameSpace,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
1
|
+
const winston = require("winston");
|
|
2
|
+
const {
|
|
3
|
+
createLogger,
|
|
4
|
+
format,
|
|
5
|
+
transports,
|
|
6
|
+
} = winston;
|
|
7
|
+
const cj = (data) => Object.keys(data).length > 0
|
|
8
|
+
? JSON.stringify(data, null, 2)
|
|
9
|
+
: null;
|
|
10
|
+
|
|
11
|
+
const isTest = process.env.NODE_ENV === "test";
|
|
12
|
+
|
|
13
|
+
const defaultLogger = new transports.Console({
|
|
14
|
+
silent: isTest,
|
|
15
|
+
level: "warn",
|
|
16
|
+
format: format.errors({stack: true}),
|
|
17
|
+
timestamp: true,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const errorLogger = new transports.Console({
|
|
21
|
+
silent: isTest,
|
|
22
|
+
format: format.errors({stack: true}),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a logger
|
|
27
|
+
*
|
|
28
|
+
* @param {String} nameSpace Namespace for the logger
|
|
29
|
+
* @param {Object} additionalData additional data to include with logging
|
|
30
|
+
* @param {string} level Default logging level to set (overwrites environment setting)
|
|
31
|
+
* @return {winston.Logger}
|
|
32
|
+
*/
|
|
33
|
+
module.exports.loggerFactory = ({
|
|
34
|
+
nameSpace = "saber",
|
|
35
|
+
additionalData = {},
|
|
36
|
+
level,
|
|
37
|
+
} = {}) => {
|
|
38
|
+
const logLevel = process.env.LOG_LEVEL || "warn";
|
|
39
|
+
const isConsole = !!(process.env.CONSOLE_LOG);
|
|
40
|
+
|
|
41
|
+
const loggerTransport = isConsole
|
|
42
|
+
? new transports.Console({
|
|
43
|
+
defaultMeta: additionalData,
|
|
44
|
+
level: level || logLevel,
|
|
45
|
+
format: format.combine(
|
|
46
|
+
format.errors({stack: true}),
|
|
47
|
+
format.cli(),
|
|
48
|
+
// eslint-disable-next-line max-len
|
|
49
|
+
format.printf(({
|
|
50
|
+
level,
|
|
51
|
+
message,
|
|
52
|
+
nameSpace,
|
|
53
|
+
stack,
|
|
54
|
+
...rest
|
|
55
|
+
}) =>
|
|
56
|
+
[
|
|
57
|
+
level,
|
|
58
|
+
`[${nameSpace}]`,
|
|
59
|
+
":",
|
|
60
|
+
message,
|
|
61
|
+
stack,
|
|
62
|
+
cj(rest),
|
|
63
|
+
].filter((value) => !!value)
|
|
64
|
+
.join(" "),
|
|
65
|
+
),
|
|
66
|
+
),
|
|
67
|
+
})
|
|
68
|
+
: defaultLogger;
|
|
69
|
+
|
|
70
|
+
const config = {
|
|
71
|
+
levels: {
|
|
72
|
+
// RFC5424
|
|
73
|
+
emerg: 0,
|
|
74
|
+
alert: 1,
|
|
75
|
+
crit: 2,
|
|
76
|
+
error: 3,
|
|
77
|
+
warning: 4,
|
|
78
|
+
notice: 5,
|
|
79
|
+
info: 6,
|
|
80
|
+
debug: 7,
|
|
81
|
+
// npm levels
|
|
82
|
+
warn: 4,
|
|
83
|
+
verbose: 6,
|
|
84
|
+
silly: 8,
|
|
85
|
+
},
|
|
86
|
+
exitOnError: false,
|
|
87
|
+
transports: [loggerTransport],
|
|
88
|
+
// Console logger from above will log errors
|
|
89
|
+
exceptionHandlers: !isConsole ? [errorLogger] : [],
|
|
90
|
+
rejectionHandlers: !isConsole ? [errorLogger] : [],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return createLogger(config)
|
|
94
|
+
.child({
|
|
95
|
+
...additionalData,
|
|
96
|
+
nameSpace: nameSpace,
|
|
97
|
+
});
|
|
98
|
+
}
|