@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.
@@ -0,0 +1,8 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npx mocha:*)",
5
+ "Bash(done)"
6
+ ]
7
+ }
8
+ }
package/.husky/pre-commit CHANGED
@@ -1,4 +1,2 @@
1
1
  #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
2
  npm run commit-ready
package/.husky/pre-push CHANGED
@@ -1,4 +1,2 @@
1
1
  #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
2
  npm run test
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
- | EXIT_DELAY | Delay for flushing the transports and exiting | 2000 | in millisecond |
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 `global.serverType` is set, it overrides `SERVER_TYPE`.
60
- If `global.serverId` is set, it overrides `SERVER_ID`.
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 encrypted part of the URL that follows the last slash in the url.
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 show 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
+ 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
- Trailing allows you to scroll through log output in real time. You can trail log data in SumoLogic.
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 logging to `error()` are added the stack trace.
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 ##
@@ -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 encrypted part of the URL that follows the last slash in the url.
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 show 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.
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
- Trailing allows you to scroll through log output in real time. You can trail log data in SumoLogic.
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 logging to `error()` are added the stack trace.
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 ##
@@ -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
- * | EXIT_DELAY | Delay for flushing the transports and exiting | 2000 | in millisecond |
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 `global.serverType` is set, it overrides `SERVER_TYPE`.
79
- * If `global.serverId` is set, it overrides `SERVER_ID`.
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
- exitDelay: parseInt(process.env.EXIT_DELAY, DECIMAL) || 2000, // in millisecond
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
- if (config.mode.includes(NONE_MODE)) return process.exit(code);
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 process.exit(code);
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 process.exit(code);
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 process.exit(code);
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.exitDelay);
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.exitDelay);
189
+ setTimeout(flushing, config.flushExitDelay);
184
190
  };
185
191
 
186
192
  logger.LEVELS = ['error', 'warn', 'info', 'verbose', 'debug', 'silly'];
@@ -158,4 +158,8 @@ export default class AwsKinesis extends Transport {
158
158
  return this.flushEvent()
159
159
  .then(() => this.emit(type, { message: `logs ${type} to ${AWS_KINESIS}` }));
160
160
  }
161
+
162
+ close() {
163
+ clearInterval(this.time);
164
+ }
161
165
  };
@@ -245,4 +245,8 @@ export default class AwsS3 extends Transport {
245
245
  .then(() => this.flushTypeEvent())
246
246
  .then(() => this.emit(type, { message: `logs ${type} to ${AWS_S3}` }));
247
247
  }
248
+
249
+ close() {
250
+ clearInterval(this.time);
251
+ }
248
252
  };
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 START_TIMEOUT = 30000; // in millisecond
38
- const FLUSH_TIMEOUT = 1000; // in millisecond
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
- FLUSH_TIMEOUT,
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
- START_TIMEOUT,
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, info, message: `could not log to ${SUMOLOGIC}` };
51
+ const resp = { endpoint: this.endpoint, data, message: `could not log to ${SUMOLOGIC}` };
52
52
 
53
- if (info && info[SPLAT] && Array.isArray(info[SPLAT])) [, resp.correlationId] = info[SPLAT];
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.11",
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.6",
35
- "@aws-sdk/client-s3": "3.993.0",
36
- "@aws-sdk/client-kinesis": "3.993.0",
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.3",
46
- "@stylistic/eslint-plugin": "5.8.0",
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",
@@ -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(START_TIMEOUT);
40
- it('Can log an debug message without a correlationId and info', (done) => {
41
- logger.debug('this is an debug statement');
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', (done) => {
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', (done) => {
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', (done) => {
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', (done) => {
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', (done) => {
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', (done) => {
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', (done) => {
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
- }, FLUSH_TIMEOUT));
77
+ }, TEST_FLUSH_TIMEOUT));
82
78
  });
83
79
 
84
80
  describe('Sumologic transport', function SumoTests() {
85
- this.timeout(START_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(START_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(START_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(START_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(START_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(START_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(START_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
+ });
@@ -1,5 +1,5 @@
1
1
  import './testEnvProdFilter.js';
2
- import { FLUSH_TIMEOUT, OK_EXIT, START_TIMEOUT } from '../lib/common.js';
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 Unit Tests', function LoggerTests() {
63
- this.timeout(START_TIMEOUT);
64
- it('Changing the environment to prod to cover filters', (done) => {
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', (done) => {
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', (done) => {
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
- }, FLUSH_TIMEOUT));
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 servier that is logged
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
- * | EXIT_DELAY | delay when existing gracefully
17
- * | NO_STACK | indicatior to log th stack on all log message
18
- * | LOG_MODE | loge mode for the running instance
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.EXIT_DELAY = 1;
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 | environement of the instance
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 | indicatior to log th stack on all log message
17
- * | LOG_MODE | loge mode for the running instance
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
  */