struct-logger 0.0.1-security → 1.0.7
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 +267 -3
- package/index.d.ts +309 -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 +39 -3
- package/test/mocks/MockAppender.js +35 -0
- package/test/mocks/MockLogger.js +52 -0
package/index.d.ts
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
///<reference lib="ES2015"/>
|
2
|
+
///<reference types="moment"/>
|
3
|
+
|
4
|
+
import moment = require("moment");
|
5
|
+
|
6
|
+
type STANDARD_LEVELS = SimpleLogger.STANDARD_LEVELS;
|
7
|
+
type Logger = SimpleLogger.Logger;
|
8
|
+
|
9
|
+
type IConsoleAppenderOptions = SimpleLogger.IConsoleAppenderOptions;
|
10
|
+
type ConsoleAppender = SimpleLogger.appenders.ConsoleAppender;
|
11
|
+
type IFileAppenderOptions = SimpleLogger.IFileAppenderOptions;
|
12
|
+
type FileAppender = SimpleLogger.appenders.FileAppender;
|
13
|
+
type IRollingFileAppenderOptions = SimpleLogger.IRollingFileAppenderOptions;
|
14
|
+
type RollingFileAppender = SimpleLogger.appenders.RollingFileAppender;
|
15
|
+
type PrepareLogger = SimpleLogger.PrepareLogger;
|
16
|
+
type AbstractAppender = SimpleLogger.AbstractAppender;
|
17
|
+
type ISimpleLoggerOptions = SimpleLogger.ISimpleLoggerOptions;
|
18
|
+
declare class SimpleLogger
|
19
|
+
{
|
20
|
+
constructor(opts?: ISimpleLoggerOptions);
|
21
|
+
createLogger(options?: SimpleLogger.ILoggerOptions): Logger;
|
22
|
+
createLogger(category?: string, level?: STANDARD_LEVELS): Logger;
|
23
|
+
createConsoleAppender(opts?: IConsoleAppenderOptions): ConsoleAppender;
|
24
|
+
createFileAppender(opts?: IFileAppenderOptions): FileAppender;
|
25
|
+
createPrepareLogger(options?: SimpleLogger.PrepareLogger): PrepareLogger;
|
26
|
+
createRollingFileAppender(opts?: IRollingFileAppenderOptions): RollingFileAppender;
|
27
|
+
addAppender<T extends AbstractAppender>(appender: AbstractAppender): T;
|
28
|
+
getAppenders(): AbstractAppender[];
|
29
|
+
getLoggers(): Logger[];
|
30
|
+
startRefreshThread(): void;
|
31
|
+
setAllLoggerLevels(level: STANDARD_LEVELS): void;
|
32
|
+
readConfig(completeCallback?: (err?: any) => void): void;
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
declare namespace SimpleLogger
|
38
|
+
{
|
39
|
+
export type STANDARD_LEVELS = 'all' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
40
|
+
interface IEntry
|
41
|
+
{
|
42
|
+
ts: moment.MomentInput;
|
43
|
+
pid: number;
|
44
|
+
domain?: string;
|
45
|
+
category?: string;
|
46
|
+
level: STANDARD_LEVELS;
|
47
|
+
msg: any | any[];
|
48
|
+
}
|
49
|
+
interface ISimpleLoggerOptions
|
50
|
+
{
|
51
|
+
domain?: string;
|
52
|
+
loggers?: Logger[];
|
53
|
+
level?: STANDARD_LEVELS;
|
54
|
+
loggerConfigFile?: string;
|
55
|
+
refresh?: number;
|
56
|
+
fs?: any;
|
57
|
+
createInterval?: typeof setInterval;
|
58
|
+
minRefresh?: number;
|
59
|
+
errorEventName?: string;
|
60
|
+
}
|
61
|
+
export interface ILoggerOptions
|
62
|
+
{
|
63
|
+
pid?: number;
|
64
|
+
errorEventName?: string;
|
65
|
+
domain?: string;
|
66
|
+
category?: string;
|
67
|
+
level?: STANDARD_LEVELS;
|
68
|
+
levels?: STANDARD_LEVELS[];
|
69
|
+
appenders?: AbstractAppender[]
|
70
|
+
}
|
71
|
+
export interface PrepareLogger
|
72
|
+
{
|
73
|
+
id?: number;
|
74
|
+
errorEventName?: string;
|
75
|
+
domain?: string;
|
76
|
+
category?: string;
|
77
|
+
level?: STANDARD_LEVELS;
|
78
|
+
levels?: STANDARD_LEVELS[];
|
79
|
+
appenders?: AbstractAppender[]
|
80
|
+
}
|
81
|
+
export namespace Logger
|
82
|
+
{
|
83
|
+
var STANDARD_LEVELS: STANDARD_LEVELS[];
|
84
|
+
var DEFAULT_LEVEL: STANDARD_LEVELS;
|
85
|
+
}
|
86
|
+
export class Logger
|
87
|
+
{
|
88
|
+
|
89
|
+
constructor(options?: ILoggerOptions);
|
90
|
+
/**
|
91
|
+
* log the statement message
|
92
|
+
*
|
93
|
+
* @param level the level of this message (label, i.e, info, warn, etc)
|
94
|
+
* @param msg
|
95
|
+
*/
|
96
|
+
log(level: STANDARD_LEVELS, msg: any[] | any): void;
|
97
|
+
|
98
|
+
/**
|
99
|
+
* set the level
|
100
|
+
*
|
101
|
+
* @param lvl one of the recognized logger levels
|
102
|
+
*/
|
103
|
+
setLevel(lvl: STANDARD_LEVELS): void;
|
104
|
+
|
105
|
+
/**
|
106
|
+
* return the current level string
|
107
|
+
*/
|
108
|
+
getLevel(): STANDARD_LEVELS;
|
109
|
+
|
110
|
+
/**
|
111
|
+
* set the list of appenders
|
112
|
+
* @param appenderList
|
113
|
+
*/
|
114
|
+
setAppenders(appenderList: AbstractAppender[]): void;
|
115
|
+
|
116
|
+
/**
|
117
|
+
* add an appender to the list
|
118
|
+
*
|
119
|
+
* @param appender - implements write method
|
120
|
+
*/
|
121
|
+
addAppender<T extends AbstractAppender>(appender: T): T;
|
122
|
+
|
123
|
+
/**
|
124
|
+
* remove the appender using the type name
|
125
|
+
*/
|
126
|
+
removeAppender(typeName: string): void;
|
127
|
+
|
128
|
+
|
129
|
+
getAppenders(): AbstractAppender[];
|
130
|
+
isDebug(): boolean;
|
131
|
+
isInfo(): boolean;
|
132
|
+
|
133
|
+
/**
|
134
|
+
* return the status map with log counts for each level
|
135
|
+
*/
|
136
|
+
getStats(): Map<STANDARD_LEVELS, number>;
|
137
|
+
|
138
|
+
getCategory(): string | undefined;
|
139
|
+
|
140
|
+
getDomain(): string | undefined;
|
141
|
+
|
142
|
+
all(...arr: any[]): void;
|
143
|
+
trace(...arr: any[]): void;
|
144
|
+
debug(...arr: any[]): void;
|
145
|
+
info(...arr: any[]): void;
|
146
|
+
warn(...arr: any[]): void;
|
147
|
+
error(...arr: any[]): void;
|
148
|
+
fatal(...arr: any[]): void;
|
149
|
+
}
|
150
|
+
|
151
|
+
export interface IAbstractAppenderOptions
|
152
|
+
{
|
153
|
+
typeName?: string;
|
154
|
+
timestampFormat?: string;
|
155
|
+
prettyPrint?: boolean;
|
156
|
+
separator?: string;
|
157
|
+
level?: STANDARD_LEVELS;
|
158
|
+
levels?: STANDARD_LEVELS[];
|
159
|
+
}
|
160
|
+
export interface IConsoleAppenderOptions extends IAbstractAppenderOptions
|
161
|
+
{
|
162
|
+
typeName?: string;
|
163
|
+
writer?: Function;
|
164
|
+
}
|
165
|
+
export interface IFileAppenderOptions extends IAbstractAppenderOptions
|
166
|
+
{
|
167
|
+
typeName?: string;
|
168
|
+
fs?: any;
|
169
|
+
autoOpen?: boolean;
|
170
|
+
logFilePath: string;
|
171
|
+
writer?: any;
|
172
|
+
}
|
173
|
+
export interface IRollingFileAppenderOptions extends IAbstractAppenderOptions
|
174
|
+
{
|
175
|
+
typeName?: string;
|
176
|
+
fs?: any;
|
177
|
+
autoOpen?: boolean;
|
178
|
+
logDirectory: string;
|
179
|
+
fileNamePattern: string;
|
180
|
+
dateFormat?: string;
|
181
|
+
currentFile?: string;
|
182
|
+
createInterval?: typeof setInterval;
|
183
|
+
}
|
184
|
+
|
185
|
+
export abstract class AbstractAppender
|
186
|
+
{
|
187
|
+
constructor(options?: IAbstractAppenderOptions);
|
188
|
+
/**
|
189
|
+
* format the entry and return the field list
|
190
|
+
*
|
191
|
+
* @param entry the log entry
|
192
|
+
* @param thisArg - use this to override the base object
|
193
|
+
*
|
194
|
+
* @returns field array
|
195
|
+
*/
|
196
|
+
formatEntry(entry: any, thisArg?: AbstractAppender): string[];
|
197
|
+
|
198
|
+
/**
|
199
|
+
* format the message
|
200
|
+
*
|
201
|
+
* @param msg the log message
|
202
|
+
* @param thisArg - use this to override the base object
|
203
|
+
*
|
204
|
+
* @returns field array
|
205
|
+
*/
|
206
|
+
formatMessage(msg: any | any[], thisArg?: AbstractAppender): string;
|
207
|
+
|
208
|
+
formatDate(value: Date): string;
|
209
|
+
formatObject(value: any): string;
|
210
|
+
formatLevel(level: STANDARD_LEVELS): string;
|
211
|
+
formatTimestamp(ts: moment.MomentInput): string;
|
212
|
+
getTypeName(): string;
|
213
|
+
|
214
|
+
//formatter(entry: any): string;
|
215
|
+
abstract write(entry: IEntry): void;
|
216
|
+
abstract setLevel(level: STANDARD_LEVELS): void;
|
217
|
+
|
218
|
+
__protected(): any;
|
219
|
+
}
|
220
|
+
|
221
|
+
//export type IConsoleAppenderOptions = appenders.IConsoleAppenderOptions;
|
222
|
+
//export type IFileAppenderOptions = appenders.IFileAppenderOptions;
|
223
|
+
//export type IRollingFileAppenderOptions = appenders.IRollingFileAppenderOptions;
|
224
|
+
|
225
|
+
export namespace appenders
|
226
|
+
{
|
227
|
+
|
228
|
+
|
229
|
+
export class ConsoleAppender extends AbstractAppender
|
230
|
+
{
|
231
|
+
constructor(options: IAbstractAppenderOptions & IConsoleAppenderOptions);
|
232
|
+
formatter(entry: IEntry): string;
|
233
|
+
write(entry: IEntry): void;
|
234
|
+
setLevel(level: STANDARD_LEVELS): void;
|
235
|
+
}
|
236
|
+
|
237
|
+
|
238
|
+
export class FileAppender extends AbstractAppender
|
239
|
+
{
|
240
|
+
constructor(options?: IFileAppenderOptions);
|
241
|
+
formatter(entry: IEntry): string;
|
242
|
+
write(entry: IEntry): void;
|
243
|
+
setLevel(level: STANDARD_LEVELS): void;
|
244
|
+
}
|
245
|
+
|
246
|
+
|
247
|
+
export class RollingFileAppender extends AbstractAppender
|
248
|
+
{
|
249
|
+
constructor(options?: IRollingFileAppenderOptions);
|
250
|
+
formatter(entry: IEntry): string;
|
251
|
+
write(entry: IEntry): void;
|
252
|
+
setLevel(level: STANDARD_LEVELS): void;
|
253
|
+
|
254
|
+
checkForRoll(now?: moment.Moment): boolean;
|
255
|
+
createFileName(now?: moment.Moment): string;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
|
260
|
+
/**
|
261
|
+
* static convenience method to create a file logger (no console logging);
|
262
|
+
*
|
263
|
+
* @param options - if string then it's the logFilePath, else options with the logFilePath
|
264
|
+
* @returns Logger
|
265
|
+
*/
|
266
|
+
export function createSimpleLogger(): Logger;
|
267
|
+
export function createPrepareLogger(): PrepareLogger;
|
268
|
+
export function createSimpleLogger(logFilePath: string): Logger;
|
269
|
+
export function createSimpleLogger(options: ISimpleLoggerOptions &
|
270
|
+
Partial<IConsoleAppenderOptions> &
|
271
|
+
Partial<IFileAppenderOptions>): Logger;
|
272
|
+
|
273
|
+
/**
|
274
|
+
* create a rolling file logger by passing options to SimpleLogger and Logger. this enables setting
|
275
|
+
* of domain, category, etc.
|
276
|
+
*
|
277
|
+
* @param options
|
278
|
+
* @returns rolling logger
|
279
|
+
*/
|
280
|
+
export function createSimpleFileLogger(logFilePath: string): Logger;
|
281
|
+
export function createSimpleFileLogger(options: ISimpleLoggerOptions &
|
282
|
+
IFileAppenderOptions): Logger;
|
283
|
+
|
284
|
+
/**
|
285
|
+
* create a rolling file appender and add it to the appender list
|
286
|
+
*
|
287
|
+
* @param options
|
288
|
+
* @returns the appender
|
289
|
+
*/
|
290
|
+
export function createRollingFileLogger(options: ISimpleLoggerOptions &
|
291
|
+
IRollingFileAppenderOptions &
|
292
|
+
{ readLoggerConfig?: Function }): Logger;
|
293
|
+
|
294
|
+
/**
|
295
|
+
* create a log manager
|
296
|
+
*
|
297
|
+
* @param options - file or rolling file specs;
|
298
|
+
*/
|
299
|
+
export function createLogManager(options?: ISimpleLoggerOptions &
|
300
|
+
Partial<IRollingFileAppenderOptions> &
|
301
|
+
Partial<IConsoleAppenderOptions> &
|
302
|
+
{ readLoggerConfig?: Function }): SimpleLogger;
|
303
|
+
}
|
304
|
+
|
305
|
+
export = SimpleLogger;
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
|
package/index.js
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
/** darryl.west@raincitysoftware.com **/
|
3
|
+
|
4
|
+
module.exports = require('./lib/SimpleLogger');
|
5
|
+
module.exports.AbstractAppender = require('./lib/AbstractAppender');
|
6
|
+
module.exports.Logger = require('./lib/Logger');
|
7
|
+
module.exports.PrepareLogger = require('./lib/PrepareLogger');
|
8
|
+
|
9
|
+
module.exports.appenders = {
|
10
|
+
ConsoleAppender:require('./lib/ConsoleAppender'),
|
11
|
+
FileAppender:require('./lib/FileAppender'),
|
12
|
+
RollingFileAppender:require('./lib/RollingFileAppender')
|
13
|
+
};
|
14
|
+
|
15
|
+
module.exports.mocks = {
|
16
|
+
MockAppender:require('./test/mocks/MockAppender'),
|
17
|
+
MockLogger:require('./test/mocks/MockLogger')
|
18
|
+
};
|
19
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
/**
|
2
|
+
* @class AbstractAppender
|
3
|
+
*
|
4
|
+
* @author: darryl.west@raincitysoftware.com
|
5
|
+
* @created: 7/7/14 5:58 PM
|
6
|
+
*/
|
7
|
+
const util = require( 'util' );
|
8
|
+
const moment = require( 'moment' );
|
9
|
+
const dash = require( 'lodash' );
|
10
|
+
|
11
|
+
const AbstractAppender = function(options) {
|
12
|
+
'use strict';
|
13
|
+
|
14
|
+
const appender = this;
|
15
|
+
const typeName = options.typeName;
|
16
|
+
const timestampFormat = options.timestampFormat || 'HH:mm:ss.SSS';
|
17
|
+
const prettyPrint = options.prettyPrint;
|
18
|
+
|
19
|
+
this.separator = options.separator || ' ';
|
20
|
+
|
21
|
+
/**
|
22
|
+
* format the entry and return the field list
|
23
|
+
*
|
24
|
+
* @param entry the log entry
|
25
|
+
* @param thisArg - use this to override the base object
|
26
|
+
*
|
27
|
+
* @returns field array
|
28
|
+
*/
|
29
|
+
this.formatEntry = function(entry, thisArg) {
|
30
|
+
const apdr = thisArg || appender;
|
31
|
+
|
32
|
+
const fields = [];
|
33
|
+
|
34
|
+
if (entry.domain) {
|
35
|
+
fields.push( entry.domain );
|
36
|
+
}
|
37
|
+
|
38
|
+
fields.push( apdr.formatTimestamp( entry.ts ) );
|
39
|
+
fields.push( apdr.formatLevel( entry.level ) );
|
40
|
+
|
41
|
+
if (entry.category) {
|
42
|
+
fields.push( entry.category );
|
43
|
+
}
|
44
|
+
|
45
|
+
fields.push( apdr.formatMessage( entry.msg ) );
|
46
|
+
|
47
|
+
return fields;
|
48
|
+
};
|
49
|
+
|
50
|
+
/**
|
51
|
+
* format the message
|
52
|
+
*
|
53
|
+
* @param msg the log message
|
54
|
+
* @param thisArg - use this to override the base object
|
55
|
+
*
|
56
|
+
* @returns field array
|
57
|
+
*/
|
58
|
+
this.formatMessage = function(msg, thisArg) {
|
59
|
+
const apdr = thisArg || appender;
|
60
|
+
|
61
|
+
if (!msg) {
|
62
|
+
return '';
|
63
|
+
}
|
64
|
+
|
65
|
+
if (util.isArray( msg )) {
|
66
|
+
const list = msg.map(function(item) {
|
67
|
+
if (util.isDate( item )) {
|
68
|
+
return apdr.formatDate( item );
|
69
|
+
} else {
|
70
|
+
return apdr.formatObject( item );
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
return list.join('');
|
75
|
+
} else {
|
76
|
+
return msg;
|
77
|
+
}
|
78
|
+
};
|
79
|
+
|
80
|
+
this.formatDate = function(value) {
|
81
|
+
return value.toJSON();
|
82
|
+
};
|
83
|
+
|
84
|
+
this.formatObject = function(value) {
|
85
|
+
if (!value) {
|
86
|
+
return '';
|
87
|
+
}
|
88
|
+
|
89
|
+
if (dash.isObject( value )) {
|
90
|
+
try {
|
91
|
+
if (value instanceof Error) {
|
92
|
+
return [
|
93
|
+
value.message,
|
94
|
+
(prettyPrint) ? JSON.stringify( value, null, 2) : JSON.stringify( value ),
|
95
|
+
value.stack
|
96
|
+
].join('\n');
|
97
|
+
}
|
98
|
+
|
99
|
+
return (prettyPrint) ? JSON.stringify( value, null, 2) : JSON.stringify( value );
|
100
|
+
} catch (ignore) {
|
101
|
+
return 'json error: ' + value.toString();
|
102
|
+
}
|
103
|
+
} else {
|
104
|
+
var s = value.toString();
|
105
|
+
if (s === '[object Object]') {
|
106
|
+
return util.inspect( value );
|
107
|
+
} else {
|
108
|
+
return s;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
};
|
112
|
+
|
113
|
+
/**
|
114
|
+
* format the level string by forcing to upper case and padding to 5 chars
|
115
|
+
*
|
116
|
+
* @param level
|
117
|
+
* @returns {string}
|
118
|
+
*/
|
119
|
+
this.formatLevel = function(level) {
|
120
|
+
let str = level.toUpperCase();
|
121
|
+
if (str.length < 5) {
|
122
|
+
str += ' ';
|
123
|
+
}
|
124
|
+
|
125
|
+
return str;
|
126
|
+
};
|
127
|
+
|
128
|
+
/**
|
129
|
+
* format the timestamp to HH:mm:ss.SSS
|
130
|
+
*
|
131
|
+
* @param ts the unix milliseconds
|
132
|
+
* @returns formatted string
|
133
|
+
*/
|
134
|
+
this.formatTimestamp = function(ts) {
|
135
|
+
return moment( ts ).format( timestampFormat );
|
136
|
+
};
|
137
|
+
|
138
|
+
/**
|
139
|
+
* return the type name of this appender (ConsoleAppender)
|
140
|
+
*/
|
141
|
+
this.getTypeName = function() {
|
142
|
+
return typeName;
|
143
|
+
};
|
144
|
+
|
145
|
+
// constructor tests
|
146
|
+
if (!typeName) {
|
147
|
+
throw new Error('appender must be constructed with a type name');
|
148
|
+
}
|
149
|
+
};
|
150
|
+
|
151
|
+
module.exports = AbstractAppender;
|
152
|
+
|
153
|
+
AbstractAppender.extend = function(child, options) {
|
154
|
+
'use strict';
|
155
|
+
|
156
|
+
const parent = new AbstractAppender( options );
|
157
|
+
|
158
|
+
dash.extend( child, parent );
|
159
|
+
|
160
|
+
return parent;
|
161
|
+
};
|
@@ -0,0 +1,57 @@
|
|
1
|
+
/**
|
2
|
+
* @class ConsoleAppender
|
3
|
+
* @classdesc ConsoleAppender writes to the console all entries at or above the specified level.
|
4
|
+
*
|
5
|
+
* @author: darryl.west@raincitysoftware.com
|
6
|
+
* @created: 7/6/14 12:02 PM
|
7
|
+
*/
|
8
|
+
const Logger = require('./Logger' );
|
9
|
+
const AbstractAppender = require('./AbstractAppender' );
|
10
|
+
|
11
|
+
/*eslint no-console: "off"*/
|
12
|
+
const ConsoleAppender = function(opts) {
|
13
|
+
'use strict';
|
14
|
+
|
15
|
+
// get a copy of the opts
|
16
|
+
const options = Object.assign({}, opts);
|
17
|
+
|
18
|
+
const appender = this;
|
19
|
+
const typeName = options.typeName || 'ConsoleAppender';
|
20
|
+
const writer = options.writer || console.log;
|
21
|
+
|
22
|
+
let level = options.level || Logger.STANDARD_LEVELS[0];
|
23
|
+
let levels = options.levels || Logger.STANDARD_LEVELS;
|
24
|
+
let currentLevel = levels.indexOf( level );
|
25
|
+
|
26
|
+
options.typeName = typeName;
|
27
|
+
AbstractAppender.extend( this, options );
|
28
|
+
|
29
|
+
/**
|
30
|
+
* default formatter for this appender;
|
31
|
+
* @param entry
|
32
|
+
*/
|
33
|
+
this.formatter = function(entry) {
|
34
|
+
const fields = appender.formatEntry( entry );
|
35
|
+
|
36
|
+
return fields.join( appender.separator );
|
37
|
+
};
|
38
|
+
|
39
|
+
/**
|
40
|
+
* call formatter then write the entry to the console output
|
41
|
+
* @param entry - the log entry
|
42
|
+
*/
|
43
|
+
this.write = function(entry) {
|
44
|
+
if (levels.indexOf( entry.level ) >= currentLevel) {
|
45
|
+
writer( appender.formatter( entry ));
|
46
|
+
}
|
47
|
+
};
|
48
|
+
|
49
|
+
this.setLevel = function(level) {
|
50
|
+
const idx = levels.indexOf( level );
|
51
|
+
if (idx >= 0) {
|
52
|
+
currentLevel = idx;
|
53
|
+
}
|
54
|
+
};
|
55
|
+
};
|
56
|
+
|
57
|
+
module.exports = ConsoleAppender;
|
@@ -0,0 +1,91 @@
|
|
1
|
+
/**
|
2
|
+
* @class FileAppender
|
3
|
+
*
|
4
|
+
* @author: darryl.west@raincitysoftware.com
|
5
|
+
* @created: 7/7/14 5:15 PM
|
6
|
+
*/
|
7
|
+
const Logger = require('./Logger' );
|
8
|
+
const AbstractAppender = require('./AbstractAppender' );
|
9
|
+
const dash = require( 'lodash' );
|
10
|
+
const path = require( 'path' );
|
11
|
+
|
12
|
+
const FileAppender = function(options) {
|
13
|
+
'use strict';
|
14
|
+
|
15
|
+
const appender = this;
|
16
|
+
const fs = options.fs || require( 'fs' );
|
17
|
+
const newline = /^win/.test(process.platform) ? '\r\n' : '\n';
|
18
|
+
const typeName = options.typeName || 'FileAppender';
|
19
|
+
const autoOpen = dash.isBoolean( options.autoOpen ) ? options.autoOpen : true;
|
20
|
+
const levels = options.levels || Logger.STANDARD_LEVELS;
|
21
|
+
|
22
|
+
let level = options.level || Logger.DEFAULT_LEVEL;
|
23
|
+
let currentLevel = levels.indexOf( level );
|
24
|
+
let logFilePath = options.logFilePath;
|
25
|
+
let writer = options.writer;
|
26
|
+
|
27
|
+
options.typeName = typeName;
|
28
|
+
AbstractAppender.extend( this, options );
|
29
|
+
|
30
|
+
/**
|
31
|
+
* default formatter for this appender;
|
32
|
+
* @param entry
|
33
|
+
*/
|
34
|
+
this.formatter = function(entry) {
|
35
|
+
const fields = appender.formatEntry( entry );
|
36
|
+
|
37
|
+
// add new line (for linux and windows)
|
38
|
+
fields.push( newline );
|
39
|
+
|
40
|
+
return fields.join( appender.separator );
|
41
|
+
};
|
42
|
+
|
43
|
+
/**
|
44
|
+
* call formatter then write the entry to the console output
|
45
|
+
* @param entry - the log entry
|
46
|
+
*/
|
47
|
+
this.write = function(entry) {
|
48
|
+
if (levels.indexOf( entry.level ) >= currentLevel) {
|
49
|
+
writer.write( appender.formatter( entry ) );
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
this.setLevel = function(level) {
|
54
|
+
const idx = levels.indexOf( level );
|
55
|
+
if (idx >= 0) {
|
56
|
+
currentLevel = idx;
|
57
|
+
}
|
58
|
+
};
|
59
|
+
|
60
|
+
// writer is opened on construction
|
61
|
+
const openWriter = function() {
|
62
|
+
if (!writer) {
|
63
|
+
const file = path.normalize( logFilePath );
|
64
|
+
const opts = {
|
65
|
+
flags:'a',
|
66
|
+
encoding:'utf8'
|
67
|
+
};
|
68
|
+
|
69
|
+
writer = fs.createWriteStream( file, opts );
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
this.closeWriter = function() {
|
74
|
+
if (writer) {
|
75
|
+
writer.end('\n');
|
76
|
+
}
|
77
|
+
};
|
78
|
+
|
79
|
+
// constructor tests
|
80
|
+
(function() {
|
81
|
+
if (!logFilePath) {
|
82
|
+
throw new Error('appender must be constructed with a log file path');
|
83
|
+
}
|
84
|
+
}());
|
85
|
+
|
86
|
+
if (autoOpen) {
|
87
|
+
openWriter();
|
88
|
+
}
|
89
|
+
};
|
90
|
+
|
91
|
+
module.exports = FileAppender;
|