@mimik/sumologic-winston-logger 2.1.11 → 2.1.12
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/.claude/settings.local.json +8 -0
- package/.husky/pre-commit +0 -2
- package/.husky/pre-push +0 -2
- package/README.md +9 -8
- package/README_Supplement.md +4 -4
- package/configuration/config.js +8 -5
- package/eslint.config.js +4 -5
- package/index.js +12 -6
- package/lib/awsKinesisTransport.js +4 -0
- package/lib/awsS3Transport.js +4 -0
- package/lib/common.js +4 -4
- package/lib/formatLib.js +2 -2
- package/lib/sumologicTransport.js +7 -2
- package/package.json +6 -6
- package/test/logger.spec.js +116 -29
- package/test/loggerProd.spec.js +8 -10
- package/test/testEnv.js +5 -5
- package/test/testEnvProdFilter.js +3 -3
package/.husky/pre-commit
CHANGED
package/.husky/pre-push
CHANGED
package/README.md
CHANGED
|
@@ -11,7 +11,8 @@ The following environment variables are used to configure the logger:
|
|
|
11
11
|
| LOG_LEVEL | Log level for the running instance | debug | |
|
|
12
12
|
| CONSOLE_LEVEL | Console log level | debug | |
|
|
13
13
|
| FILTER_FILE | Filename containing filter rules | null | |
|
|
14
|
-
|
|
|
14
|
+
| FLUSH_EXIT_DELAY | Delay for flushing the transports and exiting | 2000 | in millisecond |
|
|
15
|
+
| FLUSH_EXIT_TIMEOUT | Timeout safety net in case flush never completes | 5000 | in millisecond |
|
|
15
16
|
| NO_STACK | Whether to include call stacks in all log messages | yes | expected: yes/no |
|
|
16
17
|
| LOG_MODE | Comma-separated list defining the log mode/backends | none | enum: awsS3, awsKinesis, sumologic, all, none |
|
|
17
18
|
|
|
@@ -52,12 +53,12 @@ If `LOG_MODE` includes `awsS3`, the following environment variables are required
|
|
|
52
53
|
| S3_AWS_SECRET_ACCESS_KEY | AWS secret access key | | |
|
|
53
54
|
|
|
54
55
|
When `LOG_MODE` is `none`, logs are written to the console only.
|
|
55
|
-
When `LOG_MODE` is `all`, it is equivalent to `sumologic,awsS3
|
|
56
|
+
When `LOG_MODE` is `all`, it is equivalent to `sumologic,awsS3` (does not include `awsKinesis`).
|
|
56
57
|
|
|
57
58
|
`SERVER_TYPE` and `SERVER_ID` are used to build the S3 filename and are included in the
|
|
58
59
|
log payload for S3 and Kinesis.
|
|
59
|
-
If `
|
|
60
|
-
If `
|
|
60
|
+
If `globalThis.serverType` is set, it overrides `SERVER_TYPE`.
|
|
61
|
+
If `globalThis.serverId` is set, it overrides `SERVER_ID`.
|
|
61
62
|
|
|
62
63
|
**Kind**: global function
|
|
63
64
|
**Returns**: <code>object</code> - configuration - Logger configuration.
|
|
@@ -139,7 +140,7 @@ To find the values that you will apply the environment variables, `SUMO_LOGIC_EN
|
|
|
139
140
|
The endpoint is the part of the url that ends with a slash. i.e.
|
|
140
141
|
`https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/`
|
|
141
142
|
|
|
142
|
-
The collector code is the Base64
|
|
143
|
+
The collector code is the Base64 encoded part of the URL that follows the last slash in the url.
|
|
143
144
|
|
|
144
145
|
### `FILTER_FILE` ###
|
|
145
146
|
|
|
@@ -162,7 +163,7 @@ Formatting of SumoLogic logs is handled by this module in the following ways:
|
|
|
162
163
|
|
|
163
164
|
|
|
164
165
|
### Logging Examples ###
|
|
165
|
-
Listing 2 below
|
|
166
|
+
Listing 2 below shows you how to declare a logger to run under ECMAScript 6 and then log using the various log levels supported by the Sumologic-Winston-Logger.
|
|
166
167
|
|
|
167
168
|
``` javascript
|
|
168
169
|
import logger from '@mimik/sumologic-winston-logger';
|
|
@@ -185,7 +186,7 @@ The log() method is also supported, and adds a level parameter in position 1.
|
|
|
185
186
|
|
|
186
187
|
### Tailing ###
|
|
187
188
|
|
|
188
|
-
|
|
189
|
+
Tailing allows you to scroll through log output in real time. You can trail log data in SumoLogic.
|
|
189
190
|
|
|
190
191
|
To trail in SumoLogic go to Search > Live Tail in the SumoLogic user interface and enter `sourceCategory=<source category>` in the search bar, where `<source category>` is the log you want to trail. Then click, Run
|
|
191
192
|
|
|
@@ -194,7 +195,7 @@ To trail in SumoLogic go to Search > Live Tail in the SumoLogic user interface a
|
|
|
194
195
|
|`sourceCategory=local/node/challengeAPI/logs`|
|
|
195
196
|
|
|
196
197
|
### Stack Trace ###
|
|
197
|
-
All
|
|
198
|
+
All calls to `error()` include the stack trace.
|
|
198
199
|
All other log levels will include a line number and file name.
|
|
199
200
|
|
|
200
201
|
## License ##
|
package/README_Supplement.md
CHANGED
|
@@ -76,7 +76,7 @@ To find the values that you will apply the environment variables, `SUMO_LOGIC_EN
|
|
|
76
76
|
The endpoint is the part of the url that ends with a slash. i.e.
|
|
77
77
|
`https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/`
|
|
78
78
|
|
|
79
|
-
The collector code is the Base64
|
|
79
|
+
The collector code is the Base64 encoded part of the URL that follows the last slash in the url.
|
|
80
80
|
|
|
81
81
|
### `FILTER_FILE` ###
|
|
82
82
|
|
|
@@ -99,7 +99,7 @@ Formatting of SumoLogic logs is handled by this module in the following ways:
|
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
### Logging Examples ###
|
|
102
|
-
Listing 2 below
|
|
102
|
+
Listing 2 below shows you how to declare a logger to run under ECMAScript 6 and then log using the various log levels supported by the Sumologic-Winston-Logger.
|
|
103
103
|
|
|
104
104
|
``` javascript
|
|
105
105
|
import logger from '@mimik/sumologic-winston-logger';
|
|
@@ -122,7 +122,7 @@ The log() method is also supported, and adds a level parameter in position 1.
|
|
|
122
122
|
|
|
123
123
|
### Tailing ###
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
Tailing allows you to scroll through log output in real time. You can trail log data in SumoLogic.
|
|
126
126
|
|
|
127
127
|
To trail in SumoLogic go to Search > Live Tail in the SumoLogic user interface and enter `sourceCategory=<source category>` in the search bar, where `<source category>` is the log you want to trail. Then click, Run
|
|
128
128
|
|
|
@@ -131,7 +131,7 @@ To trail in SumoLogic go to Search > Live Tail in the SumoLogic user interface a
|
|
|
131
131
|
|`sourceCategory=local/node/challengeAPI/logs`|
|
|
132
132
|
|
|
133
133
|
### Stack Trace ###
|
|
134
|
-
All
|
|
134
|
+
All calls to `error()` include the stack trace.
|
|
135
135
|
All other log levels will include a line number and file name.
|
|
136
136
|
|
|
137
137
|
## License ##
|
package/configuration/config.js
CHANGED
|
@@ -30,7 +30,8 @@ const DECIMAL = 10;
|
|
|
30
30
|
* | LOG_LEVEL | Log level for the running instance | debug | |
|
|
31
31
|
* | CONSOLE_LEVEL | Console log level | debug | |
|
|
32
32
|
* | FILTER_FILE | Filename containing filter rules | null | |
|
|
33
|
-
* |
|
|
33
|
+
* | FLUSH_EXIT_DELAY | Delay for flushing the transports and exiting | 2000 | in millisecond |
|
|
34
|
+
* | FLUSH_EXIT_TIMEOUT | Timeout safety net in case flush never completes | 5000 | in millisecond |
|
|
34
35
|
* | NO_STACK | Whether to include call stacks in all log messages | yes | expected: yes/no |
|
|
35
36
|
* | LOG_MODE | Comma-separated list defining the log mode/backends | none | enum: awsS3, awsKinesis, sumologic, all, none |
|
|
36
37
|
*
|
|
@@ -71,12 +72,12 @@ const DECIMAL = 10;
|
|
|
71
72
|
* | S3_AWS_SECRET_ACCESS_KEY | AWS secret access key | | |
|
|
72
73
|
*
|
|
73
74
|
* When `LOG_MODE` is `none`, logs are written to the console only.
|
|
74
|
-
* When `LOG_MODE` is `all`, it is equivalent to `sumologic,awsS3
|
|
75
|
+
* When `LOG_MODE` is `all`, it is equivalent to `sumologic,awsS3` (does not include `awsKinesis`).
|
|
75
76
|
*
|
|
76
77
|
* `SERVER_TYPE` and `SERVER_ID` are used to build the S3 filename and are included in the
|
|
77
78
|
* log payload for S3 and Kinesis.
|
|
78
|
-
* If `
|
|
79
|
-
* If `
|
|
79
|
+
* If `globalThis.serverType` is set, it overrides `SERVER_TYPE`.
|
|
80
|
+
* If `globalThis.serverId` is set, it overrides `SERVER_ID`.
|
|
80
81
|
*/
|
|
81
82
|
|
|
82
83
|
const checkConfig = (config) => {
|
|
@@ -123,7 +124,8 @@ const configuration = {
|
|
|
123
124
|
filter: {
|
|
124
125
|
file: process.env.FILTER_FILE || null,
|
|
125
126
|
},
|
|
126
|
-
|
|
127
|
+
flushExitDelay: parseInt(process.env.FLUSH_EXIT_DELAY, DECIMAL) || 2000, // in millisecond
|
|
128
|
+
flushExitTimeout: parseInt(process.env.FLUSH_EXIT_TIMEOUT, DECIMAL) || 5000, // in millisecond
|
|
127
129
|
noStack: process.env.NO_STACK || 'yes',
|
|
128
130
|
};
|
|
129
131
|
configuration.mode = checkMode(process.env.LOG_MODE) || [NONE_MODE];
|
|
@@ -180,3 +182,4 @@ filter.config = filterConfig;
|
|
|
180
182
|
checkConfig(configuration);
|
|
181
183
|
|
|
182
184
|
export default configuration;
|
|
185
|
+
export { checkConfig, checkMode };
|
package/eslint.config.js
CHANGED
|
@@ -17,7 +17,7 @@ const ALLOWED_CONSTANTS = [0, 1, -1];
|
|
|
17
17
|
|
|
18
18
|
export default [
|
|
19
19
|
{
|
|
20
|
-
ignores: ['mochawesome-report/**', 'node_modules/**', 'dist/**'],
|
|
20
|
+
ignores: ['coverage/**', 'mochawesome-report/**', 'node_modules/**', 'dist/**'],
|
|
21
21
|
},
|
|
22
22
|
importPlugin.flatConfigs.recommended,
|
|
23
23
|
stylistic.configs.recommended,
|
|
@@ -29,9 +29,8 @@ export default [
|
|
|
29
29
|
languageOptions: {
|
|
30
30
|
ecmaVersion: ECMA_VERSION,
|
|
31
31
|
globals: {
|
|
32
|
+
...globals.mocha,
|
|
32
33
|
...globals.nodeBuiltin,
|
|
33
|
-
describe: 'readonly',
|
|
34
|
-
it: 'readonly',
|
|
35
34
|
},
|
|
36
35
|
sourceType: 'module',
|
|
37
36
|
},
|
|
@@ -50,7 +49,7 @@ export default [
|
|
|
50
49
|
'init-declarations': ['off'],
|
|
51
50
|
'linebreak-style': ['off'],
|
|
52
51
|
'max-depth': ['error', MAX_DEPTH],
|
|
53
|
-
'max-len': 'off',
|
|
52
|
+
'max-len': ['off'],
|
|
54
53
|
'max-lines': ['warn', { max: MAX_LINES_IN_FILES, skipComments: true, skipBlankLines: true }],
|
|
55
54
|
'max-lines-per-function': ['warn', { max: MAX_LINES_IN_FUNCTION, skipComments: true, skipBlankLines: true }],
|
|
56
55
|
'max-params': ['error', MAX_FUNCTION_PARAMETERS],
|
|
@@ -63,7 +62,7 @@ export default [
|
|
|
63
62
|
'no-undefined': ['off'],
|
|
64
63
|
'one-var': ['error', 'never'],
|
|
65
64
|
'processDoc/validate-document-env': ['error'],
|
|
66
|
-
'quotes': 'off',
|
|
65
|
+
'quotes': ['off'],
|
|
67
66
|
'sort-imports': ['error', { allowSeparatedGroups: true }],
|
|
68
67
|
'sort-keys': ['error', 'asc', { caseSensitive: true, minKeys: MIN_KEYS_IN_OBJECT, natural: false, allowLineSeparatedGroups: true }],
|
|
69
68
|
},
|
package/index.js
CHANGED
|
@@ -115,11 +115,17 @@ logger.flushAndExit = (code) => {
|
|
|
115
115
|
let awsS3Done = false;
|
|
116
116
|
let awsKinesisDone = false;
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
const doExit = () => {
|
|
119
|
+
clearTimeout(logger.safetyTimer);
|
|
120
|
+
process.exit(code);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
if (config.mode.includes(NONE_MODE)) return doExit();
|
|
124
|
+
logger.safetyTimer = setTimeout(doExit, config.flushExitTimeout); // safety net in case flush never completes
|
|
119
125
|
if (awsS3) {
|
|
120
126
|
awsS3.flush(FLUSH_EXIT);
|
|
121
127
|
awsS3.once(FLUSH_EXIT, () => {
|
|
122
|
-
if ((!sumo || sumoDone) && (!awsKinesis || awsKinesisDone)) return
|
|
128
|
+
if ((!sumo || sumoDone) && (!awsKinesis || awsKinesisDone)) return doExit();
|
|
123
129
|
awsS3Done = true;
|
|
124
130
|
return null;
|
|
125
131
|
});
|
|
@@ -127,7 +133,7 @@ logger.flushAndExit = (code) => {
|
|
|
127
133
|
if (sumo) {
|
|
128
134
|
sumo.flush(FLUSH_EXIT);
|
|
129
135
|
sumo.once(FLUSH_EXIT, () => {
|
|
130
|
-
if ((!awsS3 || awsS3Done) && (!awsKinesis || awsKinesisDone)) return
|
|
136
|
+
if ((!awsS3 || awsS3Done) && (!awsKinesis || awsKinesisDone)) return doExit();
|
|
131
137
|
sumoDone = true;
|
|
132
138
|
return null;
|
|
133
139
|
});
|
|
@@ -135,7 +141,7 @@ logger.flushAndExit = (code) => {
|
|
|
135
141
|
if (awsKinesis) {
|
|
136
142
|
awsKinesis.flush(FLUSH_EXIT);
|
|
137
143
|
awsKinesis.once(FLUSH_EXIT, () => {
|
|
138
|
-
if ((!awsS3 || awsS3Done) && (!sumo || sumoDone)) return
|
|
144
|
+
if ((!awsS3 || awsS3Done) && (!sumo || sumoDone)) return doExit();
|
|
139
145
|
awsKinesisDone = true;
|
|
140
146
|
return null;
|
|
141
147
|
});
|
|
@@ -143,7 +149,7 @@ logger.flushAndExit = (code) => {
|
|
|
143
149
|
return null;
|
|
144
150
|
};
|
|
145
151
|
|
|
146
|
-
setTimeout(flushing, config.
|
|
152
|
+
setTimeout(flushing, config.flushExitDelay);
|
|
147
153
|
};
|
|
148
154
|
|
|
149
155
|
logger.flush = () => {
|
|
@@ -180,7 +186,7 @@ logger.flush = () => {
|
|
|
180
186
|
return null;
|
|
181
187
|
};
|
|
182
188
|
|
|
183
|
-
setTimeout(flushing, config.
|
|
189
|
+
setTimeout(flushing, config.flushExitDelay);
|
|
184
190
|
};
|
|
185
191
|
|
|
186
192
|
logger.LEVELS = ['error', 'warn', 'info', 'verbose', 'debug', 'silly'];
|
package/lib/awsS3Transport.js
CHANGED
package/lib/common.js
CHANGED
|
@@ -34,8 +34,8 @@ const SYSTEM_ERROR = 500;
|
|
|
34
34
|
|
|
35
35
|
const OK_RESPONSE = 200;
|
|
36
36
|
|
|
37
|
-
const
|
|
38
|
-
const
|
|
37
|
+
const TEST_START_TIMEOUT = 30000; // in millisecond
|
|
38
|
+
const TEST_FLUSH_TIMEOUT = 1000; // in millisecond
|
|
39
39
|
const OK_EXIT = 0;
|
|
40
40
|
|
|
41
41
|
const MEGA = 1048576; // 2^20 conversion to mega
|
|
@@ -65,7 +65,7 @@ export {
|
|
|
65
65
|
ERROR,
|
|
66
66
|
FLUSH,
|
|
67
67
|
FLUSH_EXIT,
|
|
68
|
-
|
|
68
|
+
TEST_FLUSH_TIMEOUT,
|
|
69
69
|
INFO,
|
|
70
70
|
LEVEL,
|
|
71
71
|
LOG,
|
|
@@ -79,7 +79,7 @@ export {
|
|
|
79
79
|
OTHER,
|
|
80
80
|
PARTITION_KEY,
|
|
81
81
|
SPLAT,
|
|
82
|
-
|
|
82
|
+
TEST_START_TIMEOUT,
|
|
83
83
|
SUMOLOGIC,
|
|
84
84
|
SYSTEM_ERROR,
|
|
85
85
|
TEAPOT_ERROR,
|
package/lib/formatLib.js
CHANGED
|
@@ -36,7 +36,7 @@ const stackInfo = format((origInfo, opts) => {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
const correlationId = format((origInfo) => {
|
|
39
|
-
const info = origInfo;
|
|
39
|
+
const info = { ...origInfo };
|
|
40
40
|
const meta = info[SPLAT];
|
|
41
41
|
|
|
42
42
|
if (meta && typeof meta[meta.length - INDEX_ADJUST] === 'string') {
|
|
@@ -58,7 +58,7 @@ const filterMeta = format((origInfo, opts) => {
|
|
|
58
58
|
const { config } = opts;
|
|
59
59
|
const info = { ...origInfo };
|
|
60
60
|
|
|
61
|
-
const meta = info[SPLAT];
|
|
61
|
+
const meta = info[SPLAT] ? [...info[SPLAT]] : undefined;
|
|
62
62
|
let target;
|
|
63
63
|
let index;
|
|
64
64
|
|
|
@@ -48,9 +48,14 @@ export default class Sumo extends Transport {
|
|
|
48
48
|
.catch((err) => {
|
|
49
49
|
const { response } = err;
|
|
50
50
|
|
|
51
|
-
const resp = { endpoint: this.endpoint,
|
|
51
|
+
const resp = { endpoint: this.endpoint, data, message: `could not log to ${SUMOLOGIC}` };
|
|
52
52
|
|
|
53
|
-
if (
|
|
53
|
+
if (data.correlationId) resp.correlationId = data.correlationId;
|
|
54
|
+
else if (data[SPLAT] && Array.isArray(data[SPLAT])) {
|
|
55
|
+
const last = data[SPLAT][data[SPLAT].length - 1];
|
|
56
|
+
|
|
57
|
+
if (typeof last === 'string') resp.correlationId = last;
|
|
58
|
+
}
|
|
54
59
|
if (!response) {
|
|
55
60
|
resp.error = { statusCode: SYSTEM_ERROR, code: err.code, message: err.message };
|
|
56
61
|
return this.emit(WARN, resp);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mimik/sumologic-winston-logger",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.12",
|
|
4
4
|
"description": "Log wrapper for sumo, s3, kinesis and winston",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"url": "https://bitbucket.org/mimiktech/sumologic-winston-logger"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@mimik/lib-filters": "^2.0.
|
|
35
|
-
"@aws-sdk/client-s3": "3.
|
|
36
|
-
"@aws-sdk/client-kinesis": "3.
|
|
34
|
+
"@mimik/lib-filters": "^2.0.7",
|
|
35
|
+
"@aws-sdk/client-s3": "3.995.0",
|
|
36
|
+
"@aws-sdk/client-kinesis": "3.995.0",
|
|
37
37
|
"@smithy/node-http-handler": "4.4.10",
|
|
38
38
|
"axios": "1.13.5",
|
|
39
39
|
"winston": "3.19.0",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@eslint/js": "9.39.2",
|
|
44
44
|
"@mimik/eslint-plugin-document-env": "^2.0.8",
|
|
45
|
-
"@mimik/request-helper": "^2.0.
|
|
46
|
-
"@stylistic/eslint-plugin": "5.
|
|
45
|
+
"@mimik/request-helper": "^2.0.5",
|
|
46
|
+
"@stylistic/eslint-plugin": "5.9.0",
|
|
47
47
|
"aws-sdk-client-mock": "4.1.0",
|
|
48
48
|
"c8": "10.1.3",
|
|
49
49
|
"chai": "6.2.2",
|
package/test/logger.spec.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import './testEnv.js';
|
|
2
|
+
import { KinesisClient, PutRecordsCommand } from '@aws-sdk/client-kinesis';
|
|
2
3
|
import {
|
|
3
|
-
FLUSH_TIMEOUT,
|
|
4
4
|
NOT_FOUND_ERROR,
|
|
5
5
|
OK_EXIT,
|
|
6
6
|
OK_RESPONSE,
|
|
7
7
|
SPLAT,
|
|
8
|
-
START_TIMEOUT,
|
|
9
8
|
SYSTEM_ERROR,
|
|
10
9
|
TEAPOT_ERROR,
|
|
10
|
+
TEST_FLUSH_TIMEOUT,
|
|
11
|
+
TEST_START_TIMEOUT,
|
|
11
12
|
UNAUTHORIZED_ERROR,
|
|
12
13
|
} from '../lib/common.js';
|
|
13
|
-
import { KinesisClient, PutRecordsCommand } from '@aws-sdk/client-kinesis';
|
|
14
14
|
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
15
15
|
import { after, afterEach, before, beforeEach, describe, it } from 'mocha';
|
|
16
16
|
import Sumo from '../lib/sumologicTransport.js';
|
|
@@ -23,6 +23,9 @@ import { setTimeout } from 'node:timers';
|
|
|
23
23
|
import { should } from 'chai';
|
|
24
24
|
import { stub } from 'sinon';
|
|
25
25
|
|
|
26
|
+
import { checkConfig, checkMode } from '../configuration/config.js';
|
|
27
|
+
import { parseStack } from '../lib/stackLib.js';
|
|
28
|
+
|
|
26
29
|
const s3Mock = mockClient(S3Client);
|
|
27
30
|
const kinesisMock = mockClient(KinesisClient);
|
|
28
31
|
|
|
@@ -36,38 +39,30 @@ const TEST_DELAY = 200;
|
|
|
36
39
|
should();
|
|
37
40
|
|
|
38
41
|
describe('sumologic-winston-logger Unit Tests', function LoggerTests() {
|
|
39
|
-
this.timeout(
|
|
40
|
-
it('Can log
|
|
41
|
-
logger.debug('this is
|
|
42
|
-
done();
|
|
42
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
43
|
+
it('Can log a debug message without a correlationId and info', () => {
|
|
44
|
+
logger.debug('this is a debug statement');
|
|
43
45
|
});
|
|
44
|
-
it('Can log an error message without a correlationId and info', (
|
|
46
|
+
it('Can log an error message without a correlationId and info', () => {
|
|
45
47
|
logger.error('this is an error statement');
|
|
46
|
-
done();
|
|
47
48
|
});
|
|
48
|
-
it('Can log an error message without a correlationId', (
|
|
49
|
+
it('Can log an error message without a correlationId', () => {
|
|
49
50
|
logger.error('this is an error statement', { error: new Error('this is an error') });
|
|
50
|
-
done();
|
|
51
51
|
});
|
|
52
|
-
it('Can log a warning message with a correlationId', (
|
|
52
|
+
it('Can log a warning message with a correlationId', () => {
|
|
53
53
|
logger.warn('this is a warning statement', { meta: 'data' }, correlationId);
|
|
54
|
-
done();
|
|
55
54
|
});
|
|
56
|
-
it('Can log an info message', (
|
|
55
|
+
it('Can log an info message', () => {
|
|
57
56
|
logger.info('this is an info statement', { meta: 'data' });
|
|
58
|
-
done();
|
|
59
57
|
});
|
|
60
|
-
it('Can log a verbose message', (
|
|
58
|
+
it('Can log a verbose message', () => {
|
|
61
59
|
logger.verbose('this is a verbose statement', 'an extra string', { meta: 'data' });
|
|
62
|
-
done();
|
|
63
60
|
});
|
|
64
|
-
it('Can log a debug message with no object and no correlationId', (
|
|
61
|
+
it('Can log a debug message with no object and no correlationId', () => {
|
|
65
62
|
logger.debug('this is a debug statement');
|
|
66
|
-
done();
|
|
67
63
|
});
|
|
68
|
-
it('can flush logs', (
|
|
64
|
+
it('can flush logs', () => {
|
|
69
65
|
logger.flush();
|
|
70
|
-
done();
|
|
71
66
|
});
|
|
72
67
|
it('Can flush and exit', (done) => {
|
|
73
68
|
logger.debug('this is a debug statement');
|
|
@@ -76,13 +71,14 @@ describe('sumologic-winston-logger Unit Tests', function LoggerTests() {
|
|
|
76
71
|
done();
|
|
77
72
|
});
|
|
78
73
|
after(done => setTimeout(() => { // adding a delay to make sure that the flush is done
|
|
74
|
+
clearTimeout(logger.safetyTimer);
|
|
79
75
|
process.exit.restore();
|
|
80
76
|
done();
|
|
81
|
-
},
|
|
77
|
+
}, TEST_FLUSH_TIMEOUT));
|
|
82
78
|
});
|
|
83
79
|
|
|
84
80
|
describe('Sumologic transport', function SumoTests() {
|
|
85
|
-
this.timeout(
|
|
81
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
86
82
|
let server;
|
|
87
83
|
let port;
|
|
88
84
|
let sumo;
|
|
@@ -110,6 +106,7 @@ describe('Sumologic transport', function SumoTests() {
|
|
|
110
106
|
after(done => server.close(done));
|
|
111
107
|
|
|
112
108
|
beforeEach(() => {
|
|
109
|
+
sumo.removeAllListeners();
|
|
113
110
|
sumo.code = 'ok';
|
|
114
111
|
sumo.endpoint = `http://localhost:${port}/logs/`;
|
|
115
112
|
});
|
|
@@ -189,7 +186,7 @@ describe('Sumologic transport', function SumoTests() {
|
|
|
189
186
|
});
|
|
190
187
|
|
|
191
188
|
describe('S3 transport', function S3Tests() {
|
|
192
|
-
this.timeout(
|
|
189
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
193
190
|
beforeEach(() => s3Mock.resetHistory());
|
|
194
191
|
|
|
195
192
|
it('sends info logs to S3', (done) => {
|
|
@@ -268,7 +265,7 @@ describe('S3 transport', function S3Tests() {
|
|
|
268
265
|
});
|
|
269
266
|
|
|
270
267
|
describe('S3 remote transport', function S3RemoteTests() {
|
|
271
|
-
this.timeout(
|
|
268
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
272
269
|
beforeEach(() => s3Mock.resetHistory());
|
|
273
270
|
before(() => {
|
|
274
271
|
globalThis.serverType = 'mTestRemote';
|
|
@@ -319,7 +316,7 @@ describe('S3 remote transport', function S3RemoteTests() {
|
|
|
319
316
|
});
|
|
320
317
|
|
|
321
318
|
describe('S3 transport flush', function S3FlushTests() {
|
|
322
|
-
this.timeout(
|
|
319
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
323
320
|
const HIGH_MAX = 999;
|
|
324
321
|
let s3Transport;
|
|
325
322
|
let originalMaxEvents;
|
|
@@ -411,7 +408,7 @@ describe('S3 transport flush', function S3FlushTests() {
|
|
|
411
408
|
});
|
|
412
409
|
|
|
413
410
|
describe('S3 transport error handling', function S3ErrorTests() {
|
|
414
|
-
this.timeout(
|
|
411
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
415
412
|
|
|
416
413
|
afterEach(() => {
|
|
417
414
|
s3Mock.reset();
|
|
@@ -442,7 +439,7 @@ describe('S3 transport error handling', function S3ErrorTests() {
|
|
|
442
439
|
});
|
|
443
440
|
|
|
444
441
|
describe('Circular reference handling', function CircularTests() {
|
|
445
|
-
this.timeout(
|
|
442
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
446
443
|
beforeEach(() => {
|
|
447
444
|
s3Mock.resetHistory();
|
|
448
445
|
kinesisMock.resetHistory();
|
|
@@ -464,7 +461,7 @@ describe('Circular reference handling', function CircularTests() {
|
|
|
464
461
|
});
|
|
465
462
|
|
|
466
463
|
describe('Kinesis transport', function KinesisTests() {
|
|
467
|
-
this.timeout(
|
|
464
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
468
465
|
beforeEach(() => kinesisMock.resetHistory());
|
|
469
466
|
|
|
470
467
|
it('sends info logs to the info stream', (done) => {
|
|
@@ -499,3 +496,93 @@ describe('Kinesis transport', function KinesisTests() {
|
|
|
499
496
|
}, TEST_DELAY);
|
|
500
497
|
});
|
|
501
498
|
});
|
|
499
|
+
|
|
500
|
+
describe('Transport close', function CloseTests() {
|
|
501
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
502
|
+
|
|
503
|
+
it('clears the S3 interval timer on close', () => {
|
|
504
|
+
const s3Transport = logger.transports.find(tr => tr.name === 'awsS3');
|
|
505
|
+
(() => s3Transport.close()).should.not.throw();
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('clears the Kinesis interval timer on close', () => {
|
|
509
|
+
const kinesisTransport = logger.transports.find(tr => tr.name === 'awsKinesis');
|
|
510
|
+
(() => kinesisTransport.close()).should.not.throw();
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
describe('checkMode validation', function CheckModeTests() {
|
|
515
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
516
|
+
|
|
517
|
+
it('returns null for undefined mode', () => {
|
|
518
|
+
should().equal(checkMode(undefined), null);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it('returns null for falsy mode', () => {
|
|
522
|
+
should().equal(checkMode(''), null);
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it('returns array for a valid single mode', () => {
|
|
526
|
+
checkMode('awsS3').should.deep.equal(['awsS3']);
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('parses comma-separated modes', () => {
|
|
530
|
+
checkMode('awsS3, sumologic').should.deep.equal(['awsS3', 'sumologic']);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
it('expands all mode to sumologic and awsS3', () => {
|
|
534
|
+
checkMode('all').should.deep.equal(['sumologic', 'awsS3']);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it('throws when none is combined with other modes', () => {
|
|
538
|
+
(() => checkMode('none, awsS3')).should.throw('Cannot have multiple modes');
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it('throws for an invalid mode value', () => {
|
|
542
|
+
(() => checkMode('invalid')).should.throw('Invalid items in LOG_MODE');
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
describe('checkConfig validation', function CheckConfigTests() {
|
|
547
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
548
|
+
|
|
549
|
+
it('does not throw for a fully defined config', () => {
|
|
550
|
+
(() => checkConfig({ key: 'value', nested: { count: 1 } })).should.not.throw();
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it('throws for a config with undefined values', () => {
|
|
554
|
+
(() => checkConfig({ key: undefined })).should.throw('Missing values');
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('throws for a nested config with undefined values', () => {
|
|
558
|
+
(() => checkConfig({ nested: { key: undefined } })).should.throw('Missing values');
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
describe('parseStack', function ParseStackTests() {
|
|
563
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
564
|
+
|
|
565
|
+
it('returns a stackInfo object for a valid error', () => {
|
|
566
|
+
const result = parseStack(new Error('test'));
|
|
567
|
+
should().exist(result);
|
|
568
|
+
result.should.have.property('method');
|
|
569
|
+
result.should.have.property('path');
|
|
570
|
+
result.should.have.property('line');
|
|
571
|
+
result.should.have.property('pos');
|
|
572
|
+
result.should.have.property('file');
|
|
573
|
+
result.should.have.property('stack');
|
|
574
|
+
result.should.have.property('hash');
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
it('produces a 64-character hex hash', () => {
|
|
578
|
+
const result = parseStack(new Error('test'));
|
|
579
|
+
should().exist(result);
|
|
580
|
+
result.hash.should.match(/^[a-f0-9]{64}$/u);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it('returns null when all stack frames are filtered out', () => {
|
|
584
|
+
const fakeError = { stack: 'Error\n at Object.<anonymous> (node_modules/winston/foo.js:1:1)' };
|
|
585
|
+
const result = parseStack(fakeError);
|
|
586
|
+
should().equal(result, null);
|
|
587
|
+
});
|
|
588
|
+
});
|
package/test/loggerProd.spec.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './testEnvProdFilter.js';
|
|
2
|
-
import {
|
|
2
|
+
import { OK_EXIT, TEST_FLUSH_TIMEOUT, TEST_START_TIMEOUT } from '../lib/common.js';
|
|
3
3
|
import { after, describe, it } from 'mocha';
|
|
4
4
|
import { getCorrelationId } from '@mimik/request-helper';
|
|
5
5
|
import logger from '../index.js';
|
|
@@ -59,19 +59,16 @@ const user = {
|
|
|
59
59
|
|
|
60
60
|
should();
|
|
61
61
|
|
|
62
|
-
describe('sumologic-winston-logger prod
|
|
63
|
-
this.timeout(
|
|
64
|
-
it('Changing the environment to prod to cover filters', (
|
|
62
|
+
describe('sumologic-winston-logger prod filter tests', function LoggerTests() {
|
|
63
|
+
this.timeout(TEST_START_TIMEOUT);
|
|
64
|
+
it('Changing the environment to prod to cover filters', () => {
|
|
65
65
|
logger.info('this is an info statement on prod', { meta: 'data' });
|
|
66
|
-
done();
|
|
67
66
|
});
|
|
68
|
-
it('Changing the environment to prod to cover filters and see filtered result', (
|
|
67
|
+
it('Changing the environment to prod to cover filters and see filtered result', () => {
|
|
69
68
|
logger.info('this is an info statement on prod', { user }, correlationId);
|
|
70
|
-
done();
|
|
71
69
|
});
|
|
72
|
-
it('Can log a debug statement without correlationId and info on production', (
|
|
70
|
+
it('Can log a debug statement without correlationId and info on production', () => {
|
|
73
71
|
logger.debug('this is a debug statement');
|
|
74
|
-
done();
|
|
75
72
|
});
|
|
76
73
|
it('Can flush and exit', (done) => {
|
|
77
74
|
logger.debug('this is a debug statement');
|
|
@@ -80,7 +77,8 @@ describe('sumologic-winston-logger prod Unit Tests', function LoggerTests() {
|
|
|
80
77
|
done();
|
|
81
78
|
});
|
|
82
79
|
after(done => setTimeout(() => { // adding a delay to make sure that the flush is done
|
|
80
|
+
clearTimeout(logger.safetyTimer);
|
|
83
81
|
process.exit.restore();
|
|
84
82
|
done();
|
|
85
|
-
},
|
|
83
|
+
}, TEST_FLUSH_TIMEOUT));
|
|
86
84
|
});
|
package/test/testEnv.js
CHANGED
|
@@ -10,12 +10,12 @@ import process from 'node:process';
|
|
|
10
10
|
* | Env variable name | Description | Default | Comments |
|
|
11
11
|
* | ----------------- | ----------- | ------- | -------- |
|
|
12
12
|
* | SERVER_TYPE | type of the server that is logged
|
|
13
|
-
* | SERVER_ID |id of the
|
|
13
|
+
* | SERVER_ID | id of the server that is logged
|
|
14
14
|
* | LOG_LEVEL | log level of the running instance
|
|
15
15
|
* | CONSOLE_LEVEL | log level for the console of the running instance
|
|
16
|
-
* |
|
|
17
|
-
* | NO_STACK |
|
|
18
|
-
* | LOG_MODE |
|
|
16
|
+
* | FLUSH_EXIT_DELAY | delay when exiting gracefully
|
|
17
|
+
* | NO_STACK | indicator to log the stack on all log messages
|
|
18
|
+
* | LOG_MODE | log mode for the running instance
|
|
19
19
|
* | SUMO_LOGIC_ENDPOINT | url of the sumologic collector
|
|
20
20
|
* | SUMO_LOGIC_COLLECTOR_CODE | code of the sumologic collector
|
|
21
21
|
* | KINESIS_AWS_STREAM_NAME_INFO | name of the stream for info level logs
|
|
@@ -51,7 +51,7 @@ process.env.KINESIS_AWS_STREAM_NAME_ERROR = 'a kinesis stream name for error';
|
|
|
51
51
|
process.env.KINESIS_AWS_STREAM_NAME_OTHER = 'a kinesis stream name for other';
|
|
52
52
|
process.env.S3_AWS_MAX_EVENTS = 1;
|
|
53
53
|
process.env.KINESIS_AWS_MAX_EVENTS = 1;
|
|
54
|
-
process.env.
|
|
54
|
+
process.env.FLUSH_EXIT_DELAY = 1;
|
|
55
55
|
process.env.LOG_MODE = 'awsS3, sumologic, awsKinesis';
|
|
56
56
|
process.env.NO_STACK = 'yes';
|
|
57
57
|
process.env.LOG_LEVEL = 'info';
|
|
@@ -9,12 +9,12 @@ import process from 'node:process';
|
|
|
9
9
|
*
|
|
10
10
|
* | Env variable name | Description | Default | Comments |
|
|
11
11
|
* | ----------------- | ----------- | ------- | -------- |
|
|
12
|
-
* | NODE_ENV |
|
|
12
|
+
* | NODE_ENV | environment of the instance
|
|
13
13
|
* | LOG_LEVEL | log level of the running instance
|
|
14
14
|
* | CONSOLE_LEVEL | log level for the console of the running instance
|
|
15
15
|
* | FILTER_FILE | filename containing filter rules
|
|
16
|
-
* | NO_STACK |
|
|
17
|
-
* | LOG_MODE |
|
|
16
|
+
* | NO_STACK | indicator to log the stack on all log messages
|
|
17
|
+
* | LOG_MODE | log mode for the running instance
|
|
18
18
|
* | SUMO_LOGIC_ENDPOINT | url of the sumologic collector
|
|
19
19
|
* | SUMO_LOGIC_COLLECTOR_CODE | code of the sumologic collector
|
|
20
20
|
*/
|