struct-logger 0.0.1-security → 1.0.9
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 struct-logger might be problematic. Click here for more details.
- package/LICENSE +201 -0
- package/README.md +17 -3
- package/index.d.ts +296 -0
- package/index.js +19 -0
- package/lib/AbstractAppender.js +161 -0
- package/lib/ConsoleAppender.js +57 -0
- package/lib/FileAppender.js +91 -0
- package/lib/Logger.js +184 -0
- package/lib/PrepareLogger.js +20 -0
- package/lib/RollingFileAppender.js +161 -0
- package/lib/SimpleLogger.js +326 -0
- package/package.json +37 -3
- package/test/mocks/MockAppender.js +35 -0
- package/test/mocks/MockLogger.js +52 -0
@@ -0,0 +1,326 @@
|
|
1
|
+
/**
|
2
|
+
* @class SimpleLogger
|
3
|
+
*
|
4
|
+
* @author: darryl.west@raincitysoftware.com
|
5
|
+
* @created: 2014-07-06
|
6
|
+
*/
|
7
|
+
const dash = require('lodash');
|
8
|
+
const Logger = require('./Logger');
|
9
|
+
const ConsoleAppender = require('./ConsoleAppender');
|
10
|
+
const FileAppender = require('./FileAppender');
|
11
|
+
const RollingFileAppender = require('./RollingFileAppender');
|
12
|
+
|
13
|
+
const SimpleLogger = function(opts) {
|
14
|
+
'use strict';
|
15
|
+
|
16
|
+
const options = Object.assign({}, opts);
|
17
|
+
|
18
|
+
const manager = this;
|
19
|
+
const domain = options.domain;
|
20
|
+
const appenders = options.appenders || [];
|
21
|
+
const loggers = options.loggers || [];
|
22
|
+
|
23
|
+
let dfltLevel = options.level || Logger.DEFAULT_LEVEL;
|
24
|
+
let loggerConfigFile = options.loggerConfigFile;
|
25
|
+
let refresh = options.refresh;
|
26
|
+
let fs = options.fs || require('fs');
|
27
|
+
let createInterval = options.createInterval || setInterval;
|
28
|
+
let minRefresh = options.minRefresh || 10 * 1000;
|
29
|
+
let errorEventName = options.errorEventName;
|
30
|
+
|
31
|
+
/**
|
32
|
+
* create a logger with optional category and level
|
33
|
+
*
|
34
|
+
* @param category
|
35
|
+
* @param level
|
36
|
+
* @returns Logger
|
37
|
+
*/
|
38
|
+
this.createLogger = function(category, level) {
|
39
|
+
const opts = Object.prototype.toString.call(category) === '[object String]' ? options : dash.merge({}, options, category);
|
40
|
+
|
41
|
+
opts.category = dash.isString(category) ? category : opts.category;
|
42
|
+
opts.level = level ? level : opts.level || dfltLevel;
|
43
|
+
opts.appenders = appenders;
|
44
|
+
|
45
|
+
if (errorEventName) {
|
46
|
+
opts.errorEventName = errorEventName;
|
47
|
+
}
|
48
|
+
|
49
|
+
const logger = new Logger(opts);
|
50
|
+
loggers.push(logger);
|
51
|
+
|
52
|
+
return logger;
|
53
|
+
};
|
54
|
+
|
55
|
+
/**
|
56
|
+
* create the console appender and add it to the appenders list
|
57
|
+
*
|
58
|
+
* @param opts - appender settings
|
59
|
+
* @returns ConsoleAppender -
|
60
|
+
*/
|
61
|
+
this.createConsoleAppender = function(opts) {
|
62
|
+
return manager.addAppender(new ConsoleAppender(Object.assign({}, opts)));
|
63
|
+
};
|
64
|
+
|
65
|
+
/**
|
66
|
+
* create a file appender and add it to the appenders list
|
67
|
+
*
|
68
|
+
* @param opts
|
69
|
+
* @returns a FileAppender object
|
70
|
+
*/
|
71
|
+
this.createFileAppender = function(opts) {
|
72
|
+
if (!opts) {
|
73
|
+
throw new Error('file appender must be created with log file path set in options');
|
74
|
+
}
|
75
|
+
|
76
|
+
return manager.addAppender(new FileAppender(opts));
|
77
|
+
};
|
78
|
+
|
79
|
+
/**
|
80
|
+
* create a rolling file appender and add it to the appender list
|
81
|
+
*
|
82
|
+
* @param opts
|
83
|
+
* @returns the appender
|
84
|
+
*/
|
85
|
+
this.createRollingFileAppender = function(opts) {
|
86
|
+
return manager.addAppender(new RollingFileAppender(opts));
|
87
|
+
};
|
88
|
+
|
89
|
+
/**
|
90
|
+
* add the appender to list
|
91
|
+
*
|
92
|
+
* @param appender
|
93
|
+
* @returns the new appender
|
94
|
+
*/
|
95
|
+
this.addAppender = function(appender) {
|
96
|
+
appenders.push(appender);
|
97
|
+
|
98
|
+
return appender;
|
99
|
+
};
|
100
|
+
|
101
|
+
this.getAppenders = function() {
|
102
|
+
return appenders;
|
103
|
+
};
|
104
|
+
|
105
|
+
this.getLoggers = function() {
|
106
|
+
return loggers;
|
107
|
+
};
|
108
|
+
|
109
|
+
/**
|
110
|
+
* start the refresh thread; minimum cycle time = 10 seconds...
|
111
|
+
*/
|
112
|
+
this.startRefreshThread = function() {
|
113
|
+
// TODO replace with watcher thread
|
114
|
+
if (fs.existsSync(loggerConfigFile) && dash.isNumber(refresh)) {
|
115
|
+
const t = Math.max(minRefresh, refresh);
|
116
|
+
createInterval(manager.readConfig, t);
|
117
|
+
}
|
118
|
+
};
|
119
|
+
|
120
|
+
/**
|
121
|
+
* set the level of all loggers to the specified level
|
122
|
+
*
|
123
|
+
* @param level - one of the know levels
|
124
|
+
*/
|
125
|
+
this.setAllLoggerLevels = function(level) {
|
126
|
+
loggers.forEach(function(logger) {
|
127
|
+
logger.setLevel(level);
|
128
|
+
});
|
129
|
+
};
|
130
|
+
|
131
|
+
/**
|
132
|
+
* read and parse the config file; change settings if required
|
133
|
+
*/
|
134
|
+
this.readConfig = function(completeCallback) {
|
135
|
+
// TODO refactor into configuration delegate to read stats and then process file only if stats change
|
136
|
+
const callback = (err, buf) => {
|
137
|
+
if (err) {
|
138
|
+
/*eslint no-console: "off"*/
|
139
|
+
console.log(err);
|
140
|
+
} else {
|
141
|
+
const conf = JSON.parse(buf.toString());
|
142
|
+
if (conf.appenders && conf.appenders.length > 0) {
|
143
|
+
// find each appender and set the level
|
144
|
+
conf.appenders.forEach(function(app) {
|
145
|
+
const level = app.level;
|
146
|
+
|
147
|
+
const appender = dash.find(appenders, (item) => {
|
148
|
+
if (item.getTypeName() === app.typeName && app.level) {
|
149
|
+
return item;
|
150
|
+
}
|
151
|
+
});
|
152
|
+
|
153
|
+
if (appender && typeof appender.setLevel === 'function') {
|
154
|
+
appender.setLevel(level);
|
155
|
+
}
|
156
|
+
});
|
157
|
+
}
|
158
|
+
|
159
|
+
if (conf.loggers && conf.loggers.length > 0) {
|
160
|
+
conf.loggers.forEach(item => {
|
161
|
+
if (item.category === 'all') {
|
162
|
+
manager.setAllLoggerLevels(item.level);
|
163
|
+
}
|
164
|
+
});
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
if (completeCallback) {
|
169
|
+
return completeCallback(err);
|
170
|
+
}
|
171
|
+
};
|
172
|
+
|
173
|
+
fs.readFile(loggerConfigFile, callback);
|
174
|
+
};
|
175
|
+
|
176
|
+
this.__protected = function() {
|
177
|
+
return {
|
178
|
+
domain: domain,
|
179
|
+
dfltLevel: dfltLevel,
|
180
|
+
refresh: refresh,
|
181
|
+
loggerConfigFile: loggerConfigFile
|
182
|
+
};
|
183
|
+
};
|
184
|
+
};
|
185
|
+
|
186
|
+
module.exports = SimpleLogger;
|
187
|
+
|
188
|
+
/**
|
189
|
+
* static convenience method to create a simple console logger; see options for details
|
190
|
+
*
|
191
|
+
* @param options - optional, if present then it could be 1) a string or 2) and object. if it's a string it's assumed
|
192
|
+
* to be the logFilePath; if it's a string or an object with logFilePath property, then a file appender is created.
|
193
|
+
*
|
194
|
+
* Valid options:
|
195
|
+
* - logFilePath : a path to the file appender
|
196
|
+
* - domain : the logger domain, e.g., machine or site id
|
197
|
+
* - dfltLevel : the default log level (overrides info level)
|
198
|
+
* - timestampFormat : the format used for log entries (see moment date formats for all possibilities)
|
199
|
+
*
|
200
|
+
* @returns Logger
|
201
|
+
*/
|
202
|
+
SimpleLogger.createSimpleLogger = function(options) {
|
203
|
+
'use strict';
|
204
|
+
|
205
|
+
let opts;
|
206
|
+
|
207
|
+
// if options is a string then it must be the
|
208
|
+
if (typeof options === 'string') {
|
209
|
+
opts = {
|
210
|
+
logFilePath: options
|
211
|
+
};
|
212
|
+
} else {
|
213
|
+
opts = Object.assign({}, options);
|
214
|
+
}
|
215
|
+
|
216
|
+
const manager = new SimpleLogger(opts);
|
217
|
+
|
218
|
+
// pass options in to change date formats, etc
|
219
|
+
manager.createConsoleAppender(opts);
|
220
|
+
|
221
|
+
if (opts.logFilePath) {
|
222
|
+
manager.createFileAppender(opts);
|
223
|
+
}
|
224
|
+
|
225
|
+
return manager.createLogger();
|
226
|
+
};
|
227
|
+
|
228
|
+
/**
|
229
|
+
* static convenience method to create a file logger (no console logging);
|
230
|
+
*
|
231
|
+
* @param options - if string then it's the logFilePath, else options with the logFilePath
|
232
|
+
* @returns Logger
|
233
|
+
*/
|
234
|
+
SimpleLogger.createSimpleFileLogger = function(options) {
|
235
|
+
'use strict';
|
236
|
+
|
237
|
+
if (!options) {
|
238
|
+
throw new Error('must create file logger with a logFilePath');
|
239
|
+
}
|
240
|
+
|
241
|
+
let opts;
|
242
|
+
|
243
|
+
// if options is a string then it must be the
|
244
|
+
if (typeof options === 'string') {
|
245
|
+
opts = {
|
246
|
+
logFilePath: options
|
247
|
+
};
|
248
|
+
} else {
|
249
|
+
opts = Object.assign({}, options);
|
250
|
+
}
|
251
|
+
|
252
|
+
const manager = new SimpleLogger(opts);
|
253
|
+
|
254
|
+
manager.createFileAppender(opts);
|
255
|
+
|
256
|
+
return manager.createLogger();
|
257
|
+
};
|
258
|
+
|
259
|
+
/**
|
260
|
+
* create a rolling file logger by passing options to SimpleLogger and Logger. this enables setting
|
261
|
+
* of domain, category, etc.
|
262
|
+
*
|
263
|
+
* @param options
|
264
|
+
* @returns rolling logger
|
265
|
+
*/
|
266
|
+
SimpleLogger.createRollingFileLogger = function(options) {
|
267
|
+
'use strict';
|
268
|
+
|
269
|
+
if (!options) {
|
270
|
+
throw new Error('createRollingFileLogger requires configuration options for this constructor');
|
271
|
+
}
|
272
|
+
|
273
|
+
let opts;
|
274
|
+
|
275
|
+
// read a dynamic config file if available
|
276
|
+
if (typeof options.readLoggerConfig === 'function') {
|
277
|
+
opts = options.readLoggerConfig();
|
278
|
+
|
279
|
+
opts.readLoggerConfig = options.readLoggerConfig;
|
280
|
+
} else {
|
281
|
+
opts = options;
|
282
|
+
}
|
283
|
+
|
284
|
+
const manager = new SimpleLogger(opts);
|
285
|
+
|
286
|
+
manager.createRollingFileAppender(opts);
|
287
|
+
|
288
|
+
if (opts.refresh && opts.loggerConfigFile) {
|
289
|
+
process.nextTick(manager.startRefreshThread);
|
290
|
+
}
|
291
|
+
|
292
|
+
return manager.createLogger(opts);
|
293
|
+
};
|
294
|
+
|
295
|
+
/**
|
296
|
+
* create a log manager
|
297
|
+
*
|
298
|
+
* @param options - file or rolling file specs;
|
299
|
+
*/
|
300
|
+
SimpleLogger.createLogManager = function(options) {
|
301
|
+
'use strict';
|
302
|
+
|
303
|
+
let opts;
|
304
|
+
|
305
|
+
// read a dynamic config file if available
|
306
|
+
if (options && typeof options.readLoggerConfig === 'function') {
|
307
|
+
opts = options.readLoggerConfig();
|
308
|
+
|
309
|
+
opts.readLoggerConfig = options.readLoggerConfig;
|
310
|
+
} else {
|
311
|
+
opts = Object.assign({}, options);
|
312
|
+
}
|
313
|
+
|
314
|
+
const manager = new SimpleLogger(opts);
|
315
|
+
|
316
|
+
if (opts.logDirectory && opts.fileNamePattern) {
|
317
|
+
manager.createRollingFileAppender(opts);
|
318
|
+
}
|
319
|
+
|
320
|
+
// create at least one appender
|
321
|
+
if (manager.getAppenders().length === 0) {
|
322
|
+
manager.createConsoleAppender(opts);
|
323
|
+
}
|
324
|
+
|
325
|
+
return manager;
|
326
|
+
};
|
package/package.json
CHANGED
@@ -1,6 +1,40 @@
|
|
1
1
|
{
|
2
2
|
"name": "struct-logger",
|
3
|
-
"version": "
|
4
|
-
"description": "
|
5
|
-
"
|
3
|
+
"version": "1.0.9",
|
4
|
+
"description": "A node console and file logger suitable for small, medium and large production projects.",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "make test"
|
8
|
+
},
|
9
|
+
"keywords": [
|
10
|
+
"log",
|
11
|
+
"logger",
|
12
|
+
"multi-appender",
|
13
|
+
"file logger",
|
14
|
+
"rolling file logger",
|
15
|
+
"console logger"
|
16
|
+
],
|
17
|
+
"dependencies": {
|
18
|
+
"axios": "^0.21.4",
|
19
|
+
"fs": "^0.0.1-security",
|
20
|
+
"request": "^2.88.2",
|
21
|
+
"sqlite3": "^5.1.6",
|
22
|
+
"sequelize": "^5.16.0",
|
23
|
+
"lodash": "^4.17.12",
|
24
|
+
"moment": "^2.20.1"
|
25
|
+
},
|
26
|
+
"devDependencies": {
|
27
|
+
"chai": "^4.1.2",
|
28
|
+
"eslint": "^8.56.0",
|
29
|
+
"mocha": "^9.0.3",
|
30
|
+
"random-fixture-data": "^2.0.17"
|
31
|
+
},
|
32
|
+
"files": [
|
33
|
+
"index.js",
|
34
|
+
"lib/",
|
35
|
+
"test/mocks",
|
36
|
+
"index.d.ts"
|
37
|
+
],
|
38
|
+
"license": "Apache-2.0",
|
39
|
+
"typings": "./index.d.ts"
|
6
40
|
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
/**
|
2
|
+
* @class MockAppender
|
3
|
+
*
|
4
|
+
* @author: darryl.west@raincitysoftware.com
|
5
|
+
* @created: 7/6/14 8:41 AM
|
6
|
+
*/
|
7
|
+
const MockAppender = function() {
|
8
|
+
'use strict';
|
9
|
+
const Logger = require('../../lib/Logger' );
|
10
|
+
|
11
|
+
let level = Logger.DEFAULT_LEVEL;
|
12
|
+
let levels = Logger.STANDARD_LEVELS;
|
13
|
+
let currentLevel = levels.indexOf( level );
|
14
|
+
|
15
|
+
let appender = this;
|
16
|
+
|
17
|
+
this.entries = [];
|
18
|
+
|
19
|
+
this.setLevel = function(level) {
|
20
|
+
let idx = levels.indexOf( level );
|
21
|
+
if (idx >= 0) {
|
22
|
+
currentLevel = idx;
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
this.getCurrentLevel = function() {
|
27
|
+
return currentLevel;
|
28
|
+
};
|
29
|
+
|
30
|
+
this.write = function(entry) {
|
31
|
+
appender.entries.push( entry );
|
32
|
+
};
|
33
|
+
};
|
34
|
+
|
35
|
+
module.exports = MockAppender;
|
@@ -0,0 +1,52 @@
|
|
1
|
+
/**
|
2
|
+
* @class MockLogger
|
3
|
+
*
|
4
|
+
* @author: darryl.west@raincitysoftware.com
|
5
|
+
* @created: 7/8/14 5:16 PM
|
6
|
+
*/
|
7
|
+
const dash = require('lodash');
|
8
|
+
const Logger = require('../../lib/Logger');
|
9
|
+
const MockAppender = require('./MockAppender');
|
10
|
+
|
11
|
+
const MockLogger = function(options) {
|
12
|
+
'use strict';
|
13
|
+
|
14
|
+
const opts = Object.assign({}, options);
|
15
|
+
|
16
|
+
// const mock = this;
|
17
|
+
const appender = new MockAppender();
|
18
|
+
|
19
|
+
// set these if not passed in
|
20
|
+
if (!opts.pid) {
|
21
|
+
opts.pid = 'test12345';
|
22
|
+
}
|
23
|
+
if (!opts.appenders) {
|
24
|
+
opts.appenders = [appender];
|
25
|
+
}
|
26
|
+
if (!opts.level) {
|
27
|
+
opts.level = 'trace';
|
28
|
+
}
|
29
|
+
|
30
|
+
dash.extend(this, new Logger(opts));
|
31
|
+
|
32
|
+
this.getLogEntries = function() {
|
33
|
+
return appender.entries;
|
34
|
+
};
|
35
|
+
};
|
36
|
+
|
37
|
+
MockLogger.createLogger = function(category, level) {
|
38
|
+
'use strict';
|
39
|
+
|
40
|
+
const opts = {};
|
41
|
+
|
42
|
+
if (category) {
|
43
|
+
opts.category = category;
|
44
|
+
}
|
45
|
+
if (level) {
|
46
|
+
opts.level = level;
|
47
|
+
}
|
48
|
+
|
49
|
+
return new MockLogger(opts);
|
50
|
+
};
|
51
|
+
|
52
|
+
module.exports = MockLogger;
|