1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | 'use strict';
|
18 |
|
19 | const winston = require('winston');
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | module.exports = {
|
25 | |
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | getLogger(options) {
|
43 | const logToConsole = options ? options.console : true;
|
44 | const logLevel = options ? options.logLevel : 'warn';
|
45 | const fileName = options ? options.fileName : '';
|
46 | const moduleLogging = options ? options.module : {};
|
47 | const logJson = (options && typeof options.json !== 'undefined') ? options.json : false;
|
48 | const verboseLabel =
|
49 | (options && typeof options.verboseLabel !== 'undefined') ? options.verboseLabel : false;
|
50 |
|
51 | const transportOptions = {
|
52 | level: logLevel,
|
53 | timestamp() {
|
54 | return new Date().toISOString();
|
55 | },
|
56 | json: logJson,
|
57 | handleExceptions: false,
|
58 | humanReadableUnhandledException: true,
|
59 | label: getLabel(logLevel, moduleLogging, verboseLabel),
|
60 | formatter(formatOptions) {
|
61 | return getMessage.call(this, formatOptions);
|
62 | }
|
63 | };
|
64 |
|
65 | const transports = [];
|
66 |
|
67 | if (logToConsole) {
|
68 | transports.push(new (winston.transports.Console)(transportOptions));
|
69 | }
|
70 |
|
71 | if (fileName) {
|
72 | const fileOptions = transportOptions;
|
73 | fileOptions.filename = fileName;
|
74 | fileOptions.maxsize = 10485760;
|
75 | fileOptions.maxFiles = 10;
|
76 | fileOptions.tailable = true;
|
77 |
|
78 | transports.push(new (winston.transports.File)(fileOptions));
|
79 | }
|
80 |
|
81 | return new (winston.Logger)({ transports });
|
82 | }
|
83 | };
|
84 |
|
85 |
|
86 |
|
87 | function getLabel(logLevel, moduleLogging, verboseLabel) {
|
88 | let parts;
|
89 | let label = '';
|
90 |
|
91 | if (moduleLogging) {
|
92 | if (logLevel === 'debug' || logLevel === 'silly' || verboseLabel) {
|
93 | parts = moduleLogging.filename.split('/');
|
94 | label = `${parts[parts.length - 2]}/${parts.pop()}`;
|
95 | }
|
96 | }
|
97 |
|
98 | return label;
|
99 | }
|
100 |
|
101 | function getMessage(options) {
|
102 | const messageOptions = Object.assign({}, options);
|
103 |
|
104 | if (messageOptions.meta) {
|
105 | const keys = Object.keys(messageOptions.meta);
|
106 | const maskRegex = new RegExp('^pass(word|phrase)$', 'i');
|
107 | keys.forEach((key) => {
|
108 | if (maskRegex.test(key)) {
|
109 | messageOptions.meta[key] = '********';
|
110 | }
|
111 | });
|
112 | }
|
113 |
|
114 | const label = this.label ? `[pid: ${process.pid}] [${this.label}]` : '';
|
115 | const metaData =
|
116 | messageOptions.meta && Object.keys(messageOptions.meta).length ?
|
117 | `${JSON.stringify(messageOptions.meta)}` : '';
|
118 | let message =
|
119 | (messageOptions.message ? messageOptions.message.replace(/password=.+/g, 'password=********') : '');
|
120 | message = message.replace(/passphrase=.+/g, 'passphrase=********');
|
121 |
|
122 | return `${messageOptions.timestamp()} ${this.level}: ${label} ${message} ${metaData}`;
|
123 | }
|