@mimik/sumologic-winston-logger 2.1.14 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -14
- package/configuration/config.js +15 -3
- package/index.js +2 -0
- package/lib/awsKinesisTransport.js +5 -4
- package/lib/awsS3Transport.js +2 -2
- package/lib/common.js +1 -0
- package/lib/formatLib.js +28 -2
- package/lib/stackLib.js +5 -9
- package/lib/sumologicTransport.js +4 -3
- package/package.json +12 -11
- package/.claude/settings.local.json +0 -10
- package/.husky/pre-commit +0 -2
- package/.husky/pre-push +0 -2
- package/README_Supplement.md +0 -138
- package/eslint.config.js +0 -70
- package/test/filterConfig.json +0 -5
- package/test/logger.spec.js +0 -600
- package/test/loggerProd.spec.js +0 -84
- package/test/testEnv.js +0 -60
- package/test/testEnvProdFilter.js +0 -30
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# @mimik/sumologic-winston-logger
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Log wrapper for sumo, s3, kinesis and winston.
|
|
4
|
+
|
|
5
|
+
<a name="module_configuration"></a>
|
|
6
|
+
|
|
7
|
+
## configuration
|
|
4
8
|
The following environment variables are used to configure the logger:
|
|
5
9
|
|
|
6
10
|
| Env variable name | Description | Default | Comments |
|
|
@@ -13,7 +17,7 @@ The following environment variables are used to configure the logger:
|
|
|
13
17
|
| FILTER_FILE | Filename containing filter rules | null | |
|
|
14
18
|
| FLUSH_EXIT_DELAY | Delay for flushing the transports and exiting | 2000 | in millisecond |
|
|
15
19
|
| FLUSH_EXIT_TIMEOUT | Timeout safety net in case flush never completes | 5000 | in millisecond |
|
|
16
|
-
| NO_STACK |
|
|
20
|
+
| NO_STACK | Set to 'yes' to suppress stack info on non-error logs | yes | expected: yes/no |
|
|
17
21
|
| LOG_MODE | Comma-separated list defining the log mode/backends | none | enum: awsS3, awsKinesis, sumologic, all, none |
|
|
18
22
|
|
|
19
23
|
If `LOG_MODE` includes `sumologic`, the following environment variables are required:
|
|
@@ -60,15 +64,49 @@ log payload for S3 and Kinesis.
|
|
|
60
64
|
If `globalThis.serverType` is set, it overrides `SERVER_TYPE`.
|
|
61
65
|
If `globalThis.serverId` is set, it overrides `SERVER_ID`.
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
|
|
68
|
+
* [configuration](#module_configuration)
|
|
69
|
+
* [~checkConfig(config)](#module_configuration..checkConfig)
|
|
70
|
+
* [~checkMode(mode)](#module_configuration..checkMode) ⇒ <code>Array.<string></code> \| <code>null</code>
|
|
71
|
+
|
|
72
|
+
<a name="module_configuration..checkConfig"></a>
|
|
73
|
+
|
|
74
|
+
### configuration~checkConfig(config)
|
|
75
|
+
Validates that no property in the configuration tree is undefined.
|
|
76
|
+
|
|
77
|
+
**Kind**: inner method of [<code>configuration</code>](#module_configuration)
|
|
78
|
+
**Throws**:
|
|
79
|
+
|
|
80
|
+
- <code>Error</code> If any property value is undefined.
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
| Param | Type | Description |
|
|
84
|
+
| --- | --- | --- |
|
|
85
|
+
| config | <code>object</code> | The configuration object to validate. |
|
|
86
|
+
|
|
87
|
+
<a name="module_configuration..checkMode"></a>
|
|
88
|
+
|
|
89
|
+
### configuration~checkMode(mode) ⇒ <code>Array.<string></code> \| <code>null</code>
|
|
90
|
+
Parses and validates the LOG_MODE string.
|
|
91
|
+
|
|
92
|
+
**Kind**: inner method of [<code>configuration</code>](#module_configuration)
|
|
93
|
+
**Returns**: <code>Array.<string></code> \| <code>null</code> - Array of validated mode strings, or null if mode is falsy.
|
|
94
|
+
**Throws**:
|
|
95
|
+
|
|
96
|
+
- <code>Error</code> If the mode string contains invalid values.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
| Param | Type | Description |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| mode | <code>string</code> \| <code>undefined</code> | Comma-separated list of log modes. |
|
|
102
|
+
|
|
65
103
|
|
|
66
104
|
## Synopsis ##
|
|
67
105
|
|
|
68
106
|
Sumologic-Winston-Logger is a log wrapper that can write to multiple logging services.
|
|
69
107
|
Currently, Winston, SumoLogic, AWS Kinesis and AWS S3 are supported.
|
|
70
108
|
The package also adds stackTrace info.
|
|
71
|
-
StackTrace information is included in all log entries. For error-level logs, the full stack trace is added. For other log levels, method name, file name, and line number are appended.
|
|
109
|
+
StackTrace information is included in all log entries. For error-level logs, the full stack trace is added. For other log levels, method name, file name, and line number are appended. **Line formatting is not currently configurable.**
|
|
72
110
|
The package also allows some level of filtering.
|
|
73
111
|
|
|
74
112
|
## Motivation ##
|
|
@@ -118,11 +156,11 @@ The collector code as defined in SumoLogic. The Collector Code is the Base64 str
|
|
|
118
156
|
|`export SUMO_LOGIC_COLLECTOR_CODE=AhfheisdcOllectorCodeInSumoLogicuZw==`|
|
|
119
157
|
|
|
120
158
|
|
|
121
|
-
To learn more about setting this environment variable, see the section,
|
|
159
|
+
To learn more about setting this environment variable, see the section, _Finding SumoLogic endpoint and collector code_, below.
|
|
122
160
|
|
|
123
161
|
#### Finding SumoLogic endpoint and collector code ####
|
|
124
162
|
|
|
125
|
-
To find the values that you will apply the environment variables, `SUMO_LOGIC_ENDPOINT` and `SUMO_LOGIC_COLLECTOR_CODE`, in the SumoLogic Control Panel, goto: Manage > Collection, and get the source category
|
|
163
|
+
To find the values that you will apply the environment variables, `SUMO_LOGIC_ENDPOINT` and `SUMO_LOGIC_COLLECTOR_CODE`, in the SumoLogic Control Panel, goto: Manage > Collection, and get the source category
|
|
126
164
|
|
|
127
165
|

|
|
128
166
|
|
|
@@ -137,7 +175,7 @@ To find the values that you will apply the environment variables, `SUMO_LOGIC_EN
|
|
|
137
175
|
|
|
138
176
|
**Figure 3: The HTTP Source Address dialog shows collector's URL. The collector code is a Base64 string appended after the last slash in the Source Address URL**
|
|
139
177
|
|
|
140
|
-
The endpoint is the part of the url that ends with a slash.
|
|
178
|
+
The endpoint is the part of the url that ends with a slash. i.e.
|
|
141
179
|
`https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/`
|
|
142
180
|
|
|
143
181
|
The collector code is the Base64 encoded part of the URL that follows the last slash in the url.
|
|
@@ -145,7 +183,7 @@ The collector code is the Base64 encoded part of the URL that follows the last s
|
|
|
145
183
|
### `FILTER_FILE` ###
|
|
146
184
|
|
|
147
185
|
FILTER_FILE is the location where the definition of the filtering configuration is. The location has to be a full file name.
|
|
148
|
-
When
|
|
186
|
+
When a `FILTER_FILE` is specified, the content of the log will be filtered according to the log filtering configuration included in the file referred by the FILTER_FILE variable.
|
|
149
187
|
The filter will replace values of the designated property names to '-----'.
|
|
150
188
|
|
|
151
189
|
## Sample Use ##
|
|
@@ -157,9 +195,10 @@ Formatting console logs is left to winston, except that some stackTrace info is
|
|
|
157
195
|
Formatting of SumoLogic logs is handled by this module in the following ways:
|
|
158
196
|
|
|
159
197
|
* only the first argument is used as the message
|
|
160
|
-
*
|
|
198
|
+
* one metadata object can be passed as a parameter; its properties are included in the log entry
|
|
161
199
|
* structured stackTrace info is added to every log except when NO_STACK is set to 'yes'
|
|
162
200
|
* if the last parameter is a string it will be considered as a `correlationId`
|
|
201
|
+
* if the last parameter is a plain object **and** there is already an earlier metadata object, its properties are merged into the log entry at the top level (alongside `serverType`/`serverId`) — this is the _extra fields_ feature
|
|
163
202
|
|
|
164
203
|
|
|
165
204
|
### Logging Examples ###
|
|
@@ -177,9 +216,14 @@ logger.info('this is an info statement', { meta: 'data' });
|
|
|
177
216
|
logger.verbose('this is a verbose statement');
|
|
178
217
|
logger.silly('this is a silly statement o_O');
|
|
179
218
|
logger.debug('this is a debug statement with 2 params', { meta: 'data' });
|
|
180
|
-
logger.debug('this is a debug statement with 2 params and a correlationId',
|
|
219
|
+
logger.debug('this is a debug statement with 2 params and a correlationId', { meta: 'data' }, '123456');
|
|
220
|
+
|
|
221
|
+
// Extra fields — the trailing plain object is merged into the log entry at the top level.
|
|
222
|
+
// Works with or without a correlationId.
|
|
223
|
+
logger.info('this is an info statement with extra fields', { meta: 'data' }, { type: 'myService' });
|
|
224
|
+
logger.info('this is an info statement with extra fields and a correlationId', { meta: 'data' }, '123456', { type: 'myService', version: '1.0' });
|
|
181
225
|
```
|
|
182
|
-
**Listing 2: Examples of using the logger to make a log entry, using the log levels, log, silly, verbose, debug, info, warn, and error**
|
|
226
|
+
**Listing 2: Examples of using the logger to make a log entry, using the log levels, log, silly, verbose, debug, info, warn, and error**
|
|
183
227
|
|
|
184
228
|
By default, log entries are logged to console.
|
|
185
229
|
The log() method is also supported, and adds a level parameter in position 1.
|
|
@@ -194,9 +238,19 @@ To trail in SumoLogic go to Search > Live Tail in the SumoLogic user interface a
|
|
|
194
238
|
|---|
|
|
195
239
|
|`sourceCategory=local/node/challengeAPI/logs`|
|
|
196
240
|
|
|
241
|
+
### Logger API ###
|
|
242
|
+
|
|
243
|
+
In addition to the standard Winston log methods (`error`, `warn`, `info`, `verbose`, `debug`, `silly`), the logger exposes the following:
|
|
244
|
+
|
|
245
|
+
| Property / Method | Description |
|
|
246
|
+
| --- | --- |
|
|
247
|
+
| `logger.LEVELS` | Array of supported log levels in severity order: `['error', 'warn', 'info', 'verbose', 'debug', 'silly']` |
|
|
248
|
+
| `logger.flush()` | Flushes all active transports (SumoLogic, S3, Kinesis). Completes asynchronously after the configured `FLUSH_EXIT_DELAY`. |
|
|
249
|
+
| `logger.flushAndExit(code)` | Flushes all active transports and then calls `process.exit(code)`. A safety-net timer (`FLUSH_EXIT_TIMEOUT`) ensures the process exits even if a transport never responds. |
|
|
250
|
+
|
|
197
251
|
### Stack Trace ###
|
|
198
252
|
All calls to `error()` include the stack trace.
|
|
199
|
-
|
|
253
|
+
When `NO_STACK` is not set to `'yes'` and the environment is development or local, other log levels will include a line number and file name.
|
|
200
254
|
|
|
201
255
|
## License ##
|
|
202
256
|
MIT
|
package/configuration/config.js
CHANGED
|
@@ -17,8 +17,7 @@ import { readFileSync } from 'node:fs';
|
|
|
17
17
|
*
|
|
18
18
|
* Logger configuration.
|
|
19
19
|
*
|
|
20
|
-
* @
|
|
21
|
-
* @return {object} configuration - Logger configuration.
|
|
20
|
+
* @module configuration
|
|
22
21
|
* @description The following environment variables are used to configure the logger:
|
|
23
22
|
*
|
|
24
23
|
* | Env variable name | Description | Default | Comments |
|
|
@@ -31,7 +30,7 @@ import { readFileSync } from 'node:fs';
|
|
|
31
30
|
* | FILTER_FILE | Filename containing filter rules | null | |
|
|
32
31
|
* | FLUSH_EXIT_DELAY | Delay for flushing the transports and exiting | 2000 | in millisecond |
|
|
33
32
|
* | FLUSH_EXIT_TIMEOUT | Timeout safety net in case flush never completes | 5000 | in millisecond |
|
|
34
|
-
* | NO_STACK |
|
|
33
|
+
* | NO_STACK | Set to 'yes' to suppress stack info on non-error logs | yes | expected: yes/no |
|
|
35
34
|
* | LOG_MODE | Comma-separated list defining the log mode/backends | none | enum: awsS3, awsKinesis, sumologic, all, none |
|
|
36
35
|
*
|
|
37
36
|
* If `LOG_MODE` includes `sumologic`, the following environment variables are required:
|
|
@@ -79,6 +78,12 @@ import { readFileSync } from 'node:fs';
|
|
|
79
78
|
* If `globalThis.serverId` is set, it overrides `SERVER_ID`.
|
|
80
79
|
*/
|
|
81
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Validates that no property in the configuration tree is undefined.
|
|
83
|
+
*
|
|
84
|
+
* @param {object} config - The configuration object to validate.
|
|
85
|
+
* @throws {Error} If any property value is undefined.
|
|
86
|
+
*/
|
|
82
87
|
const checkConfig = (config) => {
|
|
83
88
|
const errs = [];
|
|
84
89
|
|
|
@@ -97,6 +102,13 @@ const checkConfig = (config) => {
|
|
|
97
102
|
}
|
|
98
103
|
};
|
|
99
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Parses and validates the LOG_MODE string.
|
|
107
|
+
*
|
|
108
|
+
* @param {string|undefined} mode - Comma-separated list of log modes.
|
|
109
|
+
* @returns {string[]|null} Array of validated mode strings, or null if mode is falsy.
|
|
110
|
+
* @throws {Error} If the mode string contains invalid values.
|
|
111
|
+
*/
|
|
100
112
|
const checkMode = (mode) => {
|
|
101
113
|
let logMode = null;
|
|
102
114
|
|
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from './lib/common.js';
|
|
11
11
|
import {
|
|
12
12
|
correlationId,
|
|
13
|
+
extraFields,
|
|
13
14
|
filterMeta,
|
|
14
15
|
stackInfo,
|
|
15
16
|
} from './lib/formatLib.js';
|
|
@@ -42,6 +43,7 @@ const logger = createLogger({
|
|
|
42
43
|
format: format.combine(
|
|
43
44
|
filterMeta({ env: config.env, config: config.filter.config }),
|
|
44
45
|
format.metadata(),
|
|
46
|
+
extraFields(),
|
|
45
47
|
stackInfo({ env: config.env, noStack: config.noStack }),
|
|
46
48
|
correlationId(),
|
|
47
49
|
),
|
|
@@ -73,7 +73,7 @@ export default class AwsKinesis extends Transport {
|
|
|
73
73
|
events[level].size = 0;
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
|
-
}, this.timeInterval);
|
|
76
|
+
}, this.timeInterval).unref();
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
put(Records, lvl) {
|
|
@@ -103,13 +103,14 @@ export default class AwsKinesis extends Transport {
|
|
|
103
103
|
flushEvent() {
|
|
104
104
|
return Promise.all(Object.keys(events).map((level) => {
|
|
105
105
|
if (events[level].Records.length) {
|
|
106
|
-
|
|
106
|
+
const failedRecords = events[level].Records;
|
|
107
|
+
return this.put(failedRecords, level)
|
|
107
108
|
.then(() => {
|
|
108
109
|
events[level].Records = []; // we may lose some logs due to concurrency issues
|
|
109
110
|
events[level].size = 0;
|
|
110
111
|
})
|
|
111
112
|
.catch(err => this.emit(WARN, {
|
|
112
|
-
data:
|
|
113
|
+
data: failedRecords,
|
|
113
114
|
message: `could not log to ${AWS_KINESIS}`,
|
|
114
115
|
error: { message: err.message, statusCode: err.statusCode || SYSTEM_ERROR, details: err },
|
|
115
116
|
}));
|
|
@@ -124,7 +125,7 @@ export default class AwsKinesis extends Transport {
|
|
|
124
125
|
let { level } = info;
|
|
125
126
|
const { serverType } = globalThis;
|
|
126
127
|
let { serverId } = globalThis;
|
|
127
|
-
const data =
|
|
128
|
+
const data = Object.fromEntries(Object.entries(info));
|
|
128
129
|
|
|
129
130
|
if (serverType) {
|
|
130
131
|
if (!serverId) serverId = `${UNKNOWN_ID}${CLIENTS}`;
|
package/lib/awsS3Transport.js
CHANGED
|
@@ -62,7 +62,7 @@ export default class AwsS3 extends Transport {
|
|
|
62
62
|
typeEvents[level].nbEvents = 0;
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
|
-
}, this.timeInterval);
|
|
65
|
+
}, this.timeInterval).unref();
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
put(data, lvl, date) {
|
|
@@ -184,7 +184,7 @@ export default class AwsS3 extends Transport {
|
|
|
184
184
|
const { level } = info;
|
|
185
185
|
const { serverType } = globalThis;
|
|
186
186
|
let { serverId } = globalThis;
|
|
187
|
-
const data =
|
|
187
|
+
const data = Object.fromEntries(Object.entries(info));
|
|
188
188
|
|
|
189
189
|
if (serverType) {
|
|
190
190
|
if (!serverId) serverId = `${UNKNOWN_ID}${CLIENTS}`;
|
package/lib/common.js
CHANGED
package/lib/formatLib.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DECIMAL,
|
|
2
3
|
ENV_DEV,
|
|
3
4
|
ENV_LOCAL,
|
|
4
5
|
LEVEL,
|
|
@@ -10,6 +11,7 @@ import { logs } from '@mimik/lib-filters';
|
|
|
10
11
|
import { parseStack } from './stackLib.js';
|
|
11
12
|
|
|
12
13
|
const INDEX_ADJUST = 1;
|
|
14
|
+
const MIN_EXTRA_FIELDS_ARGS = 2;
|
|
13
15
|
|
|
14
16
|
const isReserved = (value) => {
|
|
15
17
|
if (value === LEVEL || value === 'level') return true;
|
|
@@ -49,8 +51,7 @@ const correlationId = format((origInfo) => {
|
|
|
49
51
|
|
|
50
52
|
([info.correlationId, info.step] = resultsSteps);
|
|
51
53
|
}
|
|
52
|
-
|
|
53
|
-
if (info.step) info.step = parseInt(info.step, 10);
|
|
54
|
+
if (info.step) info.step = parseInt(info.step, DECIMAL);
|
|
54
55
|
return info;
|
|
55
56
|
});
|
|
56
57
|
|
|
@@ -99,8 +100,33 @@ const filterMeta = format((origInfo, opts) => {
|
|
|
99
100
|
return info;
|
|
100
101
|
});
|
|
101
102
|
|
|
103
|
+
const extraFields = format((origInfo) => {
|
|
104
|
+
const info = { ...origInfo };
|
|
105
|
+
const meta = info[SPLAT] ? [...info[SPLAT]] : undefined;
|
|
106
|
+
|
|
107
|
+
if (!meta || meta.length < MIN_EXTRA_FIELDS_ARGS) return info;
|
|
108
|
+
|
|
109
|
+
const last = meta[meta.length - 1];
|
|
110
|
+
if (typeof last !== 'object' || last === null || Array.isArray(last)) return info;
|
|
111
|
+
|
|
112
|
+
const hasOtherObject = meta.slice(0, -1).some(
|
|
113
|
+
item => typeof item === 'object' && item !== null && !Array.isArray(item),
|
|
114
|
+
);
|
|
115
|
+
if (!hasOtherObject) return info;
|
|
116
|
+
|
|
117
|
+
Object.entries(last).forEach(([key, value]) => {
|
|
118
|
+
if (!isReserved(key)) {
|
|
119
|
+
info[key] = value;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
info[SPLAT] = meta.slice(0, -1);
|
|
124
|
+
return info;
|
|
125
|
+
});
|
|
126
|
+
|
|
102
127
|
export {
|
|
103
128
|
stackInfo,
|
|
104
129
|
correlationId,
|
|
130
|
+
extraFields,
|
|
105
131
|
filterMeta,
|
|
106
132
|
};
|
package/lib/stackLib.js
CHANGED
|
@@ -2,7 +2,7 @@ import { basename } from 'node:path';
|
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
|
|
5
|
-
// Stack trace format
|
|
5
|
+
// Stack trace format:
|
|
6
6
|
// https://github.com/v8/v8/wiki/Stack%20Trace%20API
|
|
7
7
|
// these regexes are used to pull out the parts of the stack trace like method name, line number, etc.
|
|
8
8
|
const STACKREG = /at\s+(?<method>.*)\s+\((?<path>.*):(?<line>\d*):(?<position>\d*)\)/iu;
|
|
@@ -34,20 +34,16 @@ const parseStack = (newError) => {
|
|
|
34
34
|
const stackParts = STACKREG.exec(firstLine) || STACKREG2.exec(firstLine);
|
|
35
35
|
|
|
36
36
|
if (!stackParts || stackParts.length !== ALL_STACK) return null;
|
|
37
|
-
const
|
|
37
|
+
const stack = `${SHIFT}${truncatedList.join('\n').trimStart()}`;
|
|
38
|
+
return {
|
|
38
39
|
method: stackParts[METHOD],
|
|
39
40
|
path: stackParts[PATH],
|
|
40
41
|
line: stackParts[LINE],
|
|
41
42
|
pos: stackParts[POSITION],
|
|
42
43
|
file: basename(stackParts[PATH]),
|
|
43
|
-
stack
|
|
44
|
+
stack,
|
|
45
|
+
hash: createHash('sha256').update(stack).digest('hex'),
|
|
44
46
|
};
|
|
45
|
-
stackInfo.hash = createHash('sha256')
|
|
46
|
-
.update(stackInfo.stack)
|
|
47
|
-
.digest('hex');
|
|
48
|
-
// this is a hash of the stack trace for easier searching for the stack trace
|
|
49
|
-
// security of this is not a concern since the stack trace is also sent unencrypted
|
|
50
|
-
return stackInfo;
|
|
51
47
|
};
|
|
52
48
|
|
|
53
49
|
export {
|
|
@@ -28,7 +28,8 @@ export default class Sumo extends Transport {
|
|
|
28
28
|
log(info, callback) {
|
|
29
29
|
const { serverType } = globalThis;
|
|
30
30
|
let { serverId } = globalThis;
|
|
31
|
-
const
|
|
31
|
+
const splatArgs = info[SPLAT];
|
|
32
|
+
const data = Object.fromEntries(Object.entries(info));
|
|
32
33
|
|
|
33
34
|
if (serverType) {
|
|
34
35
|
if (!serverId) serverId = `${UNKNOWN_ID}${CLIENTS}`;
|
|
@@ -51,8 +52,8 @@ export default class Sumo extends Transport {
|
|
|
51
52
|
const resp = { endpoint: this.endpoint, data, message: `could not log to ${SUMOLOGIC}` };
|
|
52
53
|
|
|
53
54
|
if (data.correlationId) resp.correlationId = data.correlationId;
|
|
54
|
-
else if (
|
|
55
|
-
const last =
|
|
55
|
+
else if (splatArgs && Array.isArray(splatArgs)) {
|
|
56
|
+
const last = splatArgs[splatArgs.length - 1];
|
|
56
57
|
|
|
57
58
|
if (typeof last === 'string') resp.correlationId = last;
|
|
58
59
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mimik/sumologic-winston-logger",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Log wrapper for sumo, s3, kinesis and winston",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"lint": "eslint . --no-error-on-unmatched-pattern",
|
|
13
|
-
"docs": "jsdoc2md configuration/config.js > README.md
|
|
13
|
+
"docs": "jsdoc2md --template docs/README.hbs configuration/config.js > README.md",
|
|
14
14
|
"test": "mocha --reporter mochawesome --bail --exit --check-leaks --global serverType,serverId test/logger.spec.js test/loggerProd.spec.js",
|
|
15
15
|
"test-ci": "c8 --reporter=lcov --reporter=text npm test",
|
|
16
16
|
"prepublishOnly": "npm run docs && npm run lint && npm run test-ci",
|
|
@@ -32,29 +32,30 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@mimik/lib-filters": "^2.0.7",
|
|
35
|
-
"@aws-sdk/client-s3": "3.
|
|
36
|
-
"@aws-sdk/client-kinesis": "3.
|
|
37
|
-
"@smithy/node-http-handler": "4.4.
|
|
38
|
-
"axios": "1.13.
|
|
35
|
+
"@aws-sdk/client-s3": "3.1006.0",
|
|
36
|
+
"@aws-sdk/client-kinesis": "3.1006.0",
|
|
37
|
+
"@smithy/node-http-handler": "4.4.14",
|
|
38
|
+
"axios": "1.13.6",
|
|
39
39
|
"winston": "3.19.0",
|
|
40
40
|
"winston-transport": "4.9.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@eslint/js": "9.39.
|
|
43
|
+
"@eslint/js": "9.39.4",
|
|
44
44
|
"@mimik/eslint-plugin-document-env": "^2.0.8",
|
|
45
|
+
"@mimik/eslint-plugin-logger": "^1.0.2",
|
|
45
46
|
"@mimik/request-helper": "^2.0.5",
|
|
46
|
-
"@stylistic/eslint-plugin": "5.
|
|
47
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
47
48
|
"aws-sdk-client-mock": "4.1.0",
|
|
48
49
|
"c8": "11.0.0",
|
|
49
50
|
"chai": "6.2.2",
|
|
50
|
-
"eslint": "9.39.
|
|
51
|
+
"eslint": "9.39.4",
|
|
51
52
|
"eslint-plugin-import": "2.32.0",
|
|
52
53
|
"express": "5.2.1",
|
|
53
|
-
"globals": "17.
|
|
54
|
+
"globals": "17.4.0",
|
|
54
55
|
"husky": "9.1.7",
|
|
55
56
|
"jsdoc-to-markdown": "9.1.3",
|
|
56
57
|
"mocha": "11.7.5",
|
|
57
58
|
"mochawesome": "7.1.4",
|
|
58
|
-
"sinon": "21.0.
|
|
59
|
+
"sinon": "21.0.2"
|
|
59
60
|
}
|
|
60
61
|
}
|
package/.husky/pre-commit
DELETED
package/.husky/pre-push
DELETED
package/README_Supplement.md
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
## Synopsis ##
|
|
3
|
-
|
|
4
|
-
Sumologic-Winston-Logger is a log wrapper that can write to multiple logging services.
|
|
5
|
-
Currently, Winston, SumoLogic, AWS Kinesis and AWS S3 are supported.
|
|
6
|
-
The package also adds stackTrace info.
|
|
7
|
-
StackTrace information is included in all log entries. For error-level logs, the full stack trace is added. For other log levels, method name, file name, and line number are appended. **Line formatting is not currently configurable.**
|
|
8
|
-
The package also allows some level of filtering.
|
|
9
|
-
|
|
10
|
-
## Motivation ##
|
|
11
|
-
To centralize logging in a single npm node package
|
|
12
|
-
|
|
13
|
-
## Installation ##
|
|
14
|
-
|
|
15
|
-
The logger is discoverable on npmjs.org.
|
|
16
|
-
|
|
17
|
-
To install:
|
|
18
|
-
```
|
|
19
|
-
npm install @mimik/sumologic-winston-logger --save
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Configuration - Details ##
|
|
23
|
-
|
|
24
|
-
The following sections describe the details of each of the environment variables listed above.
|
|
25
|
-
|
|
26
|
-
### `LOG_LEVEL` ###
|
|
27
|
-
Log levels supported inclusively according to the following list, as borrowed from winston:
|
|
28
|
-
|
|
29
|
-
* silly
|
|
30
|
-
* verbose
|
|
31
|
-
* debug
|
|
32
|
-
* info
|
|
33
|
-
* warn
|
|
34
|
-
* error
|
|
35
|
-
|
|
36
|
-
Thus, if one declares a log level of silly, the levels error, warn, info, debug, and verbose are reported too.
|
|
37
|
-
|
|
38
|
-
|Example to set the environment variable `LOG_LEVEL`|
|
|
39
|
-
|---|
|
|
40
|
-
|`export LOG_LEVEL=error`|
|
|
41
|
-
|
|
42
|
-
### `SUMO_LOGIC_ENDPOINT` ###
|
|
43
|
-
The endpoint defined in SumoLogic to where log information will be sent. See the section, _Finding SumoLogic endpoint and collector code_, below to find the value to assign to this environment variable.
|
|
44
|
-
|
|
45
|
-
|Example to set the environment variable `SUMO_LOGIC_ENDPOINT`|
|
|
46
|
-
|---|
|
|
47
|
-
|`export SUMO_LOGIC_ENDPOINT=https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/`|
|
|
48
|
-
|
|
49
|
-
### `SUMO_LOGIC_COLLECTOR_CODE` ###
|
|
50
|
-
The collector code as defined in SumoLogic. The Collector Code is the Base64 string that appears after the last slash in the URL defined in the SumoLogic Control Panel.
|
|
51
|
-
|
|
52
|
-
|Example to set the environment variable `SUMO_LOGIC_COLLECTOR_CODE`|
|
|
53
|
-
|---|
|
|
54
|
-
|`export SUMO_LOGIC_COLLECTOR_CODE=AhfheisdcOllectorCodeInSumoLogicuZw==`|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
To learn more about setting this environment variable, see the section, _Finding SumoLogic endpoint and collector code_, below.
|
|
58
|
-
|
|
59
|
-
#### Finding SumoLogic endpoint and collector code ####
|
|
60
|
-
|
|
61
|
-
To find the values that you will apply the environment variables, `SUMO_LOGIC_ENDPOINT` and `SUMO_LOGIC_COLLECTOR_CODE`, in the SumoLogic Control Panel, goto: Manage > Collection, and get the source category
|
|
62
|
-
|
|
63
|
-

|
|
64
|
-
|
|
65
|
-
**Figure 1: Select the Manage -> Collection to display a list of collectors in force**
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-

|
|
69
|
-
|
|
70
|
-
**Figure 2: Click the link, Show URL to display the URL configuration for the given collector**
|
|
71
|
-
|
|
72
|
-

|
|
73
|
-
|
|
74
|
-
**Figure 3: The HTTP Source Address dialog shows collector's URL. The collector code is a Base64 string appended after the last slash in the Source Address URL**
|
|
75
|
-
|
|
76
|
-
The endpoint is the part of the url that ends with a slash. i.e.
|
|
77
|
-
`https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/`
|
|
78
|
-
|
|
79
|
-
The collector code is the Base64 encoded part of the URL that follows the last slash in the url.
|
|
80
|
-
|
|
81
|
-
### `FILTER_FILE` ###
|
|
82
|
-
|
|
83
|
-
FILTER_FILE is the location where the definition of the filtering configuration is. The location has to be a full file name.
|
|
84
|
-
When the environment (NODE_ENV) in which the logger is used is `prod` or `production`, the content of the log will be filtered according to the log filtering configuration included in the file referred by the FILTER_FILE variable.
|
|
85
|
-
The filter will replace values of the designated property names to '-----'.
|
|
86
|
-
|
|
87
|
-
## Sample Use ##
|
|
88
|
-
|
|
89
|
-
The intent of this package is to support all the behavior common to console.log while also including support of multiple arguments and all data types.
|
|
90
|
-
|
|
91
|
-
Formatting console logs is left to winston, except that some stackTrace info is appended to each line.
|
|
92
|
-
|
|
93
|
-
Formatting of SumoLogic logs is handled by this module in the following ways:
|
|
94
|
-
|
|
95
|
-
* only the first argument is used as the message
|
|
96
|
-
* only one object can be passed as parameter
|
|
97
|
-
* structured stackTrace info is added to every log except when NO_STACK is set to 'yes'
|
|
98
|
-
* if the last parameter is a string it will be considered as a `correlationId`
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
### Logging Examples ###
|
|
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
|
-
|
|
104
|
-
``` javascript
|
|
105
|
-
import logger from '@mimik/sumologic-winston-logger';
|
|
106
|
-
|
|
107
|
-
logger.log('debug', 'this is a debug statement using log');
|
|
108
|
-
logger.debug({ message: 'this is a debug statement using an object'});
|
|
109
|
-
logger.error('this is an error statement');
|
|
110
|
-
logger.error(new Error('this is an error statement'));
|
|
111
|
-
logger.warn('this is a warning statement', { meta: 'data' });
|
|
112
|
-
logger.info('this is an info statement', { meta: 'data' });
|
|
113
|
-
logger.verbose('this is a verbose statement');
|
|
114
|
-
logger.silly('this is a silly statement o_O');
|
|
115
|
-
logger.debug('this is a debug statement with 2 params', { meta: 'data' });
|
|
116
|
-
logger.debug('this is a debug statement with 2 params and a correlationId', { meta: 'data' }, '123456')
|
|
117
|
-
```
|
|
118
|
-
**Listing 2: Examples of using the logger to make a log entry, using the log levels, log, silly, verbose, debug, info, warn, and error**
|
|
119
|
-
|
|
120
|
-
By default, log entries are logged to console.
|
|
121
|
-
The log() method is also supported, and adds a level parameter in position 1.
|
|
122
|
-
|
|
123
|
-
### Tailing ###
|
|
124
|
-
|
|
125
|
-
Tailing allows you to scroll through log output in real time. You can trail log data in SumoLogic.
|
|
126
|
-
|
|
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
|
-
|
|
129
|
-
|Example|
|
|
130
|
-
|---|
|
|
131
|
-
|`sourceCategory=local/node/challengeAPI/logs`|
|
|
132
|
-
|
|
133
|
-
### Stack Trace ###
|
|
134
|
-
All calls to `error()` include the stack trace.
|
|
135
|
-
All other log levels will include a line number and file name.
|
|
136
|
-
|
|
137
|
-
## License ##
|
|
138
|
-
MIT
|