source: trip-planner-front/node_modules/log4js/lib/layouts.js@ 84d0fbb

Last change on this file since 84d0fbb was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 9.7 KB
Line 
1const dateFormat = require('date-format');
2const os = require('os');
3const util = require('util');
4const path = require('path');
5
6const styles = {
7 // styles
8 bold: [1, 22],
9 italic: [3, 23],
10 underline: [4, 24],
11 inverse: [7, 27],
12 // grayscale
13 white: [37, 39],
14 grey: [90, 39],
15 black: [90, 39],
16 // colors
17 blue: [34, 39],
18 cyan: [36, 39],
19 green: [32, 39],
20 magenta: [35, 39],
21 red: [91, 39],
22 yellow: [33, 39]
23};
24
25function colorizeStart(style) {
26 return style ? `\x1B[${styles[style][0]}m` : '';
27}
28
29function colorizeEnd(style) {
30 return style ? `\x1B[${styles[style][1]}m` : '';
31}
32
33/**
34 * Taken from masylum's fork (https://github.com/masylum/log4js-node)
35 */
36function colorize(str, style) {
37 return colorizeStart(style) + str + colorizeEnd(style);
38}
39
40function timestampLevelAndCategory(loggingEvent, colour) {
41 return colorize(
42 util.format(
43 '[%s] [%s] %s - ',
44 dateFormat.asString(loggingEvent.startTime),
45 loggingEvent.level.toString(),
46 loggingEvent.categoryName
47 ),
48 colour
49 );
50}
51
52/**
53 * BasicLayout is a simple layout for storing the logs. The logs are stored
54 * in following format:
55 * <pre>
56 * [startTime] [logLevel] categoryName - message\n
57 * </pre>
58 *
59 * @author Stephan Strittmatter
60 */
61function basicLayout(loggingEvent) {
62 return timestampLevelAndCategory(loggingEvent) + util.format(...loggingEvent.data);
63}
64
65/**
66 * colouredLayout - taken from masylum's fork.
67 * same as basicLayout, but with colours.
68 */
69function colouredLayout(loggingEvent) {
70 return timestampLevelAndCategory(loggingEvent, loggingEvent.level.colour) + util.format(...loggingEvent.data);
71}
72
73function messagePassThroughLayout(loggingEvent) {
74 return util.format(...loggingEvent.data);
75}
76
77function dummyLayout(loggingEvent) {
78 return loggingEvent.data[0];
79}
80
81/**
82 * PatternLayout
83 * Format for specifiers is %[padding].[truncation][field]{[format]}
84 * e.g. %5.10p - left pad the log level by 5 characters, up to a max of 10
85 * both padding and truncation can be negative.
86 * Negative truncation = trunc from end of string
87 * Positive truncation = trunc from start of string
88 * Negative padding = pad right
89 * Positive padding = pad left
90 *
91 * Fields can be any of:
92 * - %r time in toLocaleTimeString format
93 * - %p log level
94 * - %c log category
95 * - %h hostname
96 * - %m log data
97 * - %d date in constious formats
98 * - %% %
99 * - %n newline
100 * - %z pid
101 * - %f filename
102 * - %l line number
103 * - %o column postion
104 * - %s call stack
105 * - %x{<tokenname>} add dynamic tokens to your log. Tokens are specified in the tokens parameter
106 * - %X{<tokenname>} add dynamic tokens to your log. Tokens are specified in logger context
107 * You can use %[ and %] to define a colored block.
108 *
109 * Tokens are specified as simple key:value objects.
110 * The key represents the token name whereas the value can be a string or function
111 * which is called to extract the value to put in the log message. If token is not
112 * found, it doesn't replace the field.
113 *
114 * A sample token would be: { 'pid' : function() { return process.pid; } }
115 *
116 * Takes a pattern string, array of tokens and returns a layout function.
117 * @return {Function}
118 * @param pattern
119 * @param tokens
120 * @param timezoneOffset
121 *
122 * @authors ['Stephan Strittmatter', 'Jan Schmidle']
123 */
124function patternLayout(pattern, tokens) {
125 const TTCC_CONVERSION_PATTERN = '%r %p %c - %m%n';
126 const regex = /%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;
127
128 pattern = pattern || TTCC_CONVERSION_PATTERN;
129
130 function categoryName(loggingEvent, specifier) {
131 let loggerName = loggingEvent.categoryName;
132 if (specifier) {
133 const precision = parseInt(specifier, 10);
134 const loggerNameBits = loggerName.split('.');
135 if (precision < loggerNameBits.length) {
136 loggerName = loggerNameBits.slice(loggerNameBits.length - precision).join('.');
137 }
138 }
139 return loggerName;
140 }
141
142 function formatAsDate(loggingEvent, specifier) {
143 let format = dateFormat.ISO8601_FORMAT;
144 if (specifier) {
145 format = specifier;
146 // Pick up special cases
147 if (format === 'ISO8601') {
148 format = dateFormat.ISO8601_FORMAT;
149 } else if (format === 'ISO8601_WITH_TZ_OFFSET') {
150 format = dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT;
151 } else if (format === 'ABSOLUTE') {
152 format = dateFormat.ABSOLUTETIME_FORMAT;
153 } else if (format === 'DATE') {
154 format = dateFormat.DATETIME_FORMAT;
155 }
156 }
157 // Format the date
158 return dateFormat.asString(format, loggingEvent.startTime);
159 }
160
161 function hostname() {
162 return os.hostname().toString();
163 }
164
165 function formatMessage(loggingEvent) {
166 return util.format(...loggingEvent.data);
167 }
168
169 function endOfLine() {
170 return os.EOL;
171 }
172
173 function logLevel(loggingEvent) {
174 return loggingEvent.level.toString();
175 }
176
177 function startTime(loggingEvent) {
178 return dateFormat.asString('hh:mm:ss', loggingEvent.startTime);
179 }
180
181 function startColour(loggingEvent) {
182 return colorizeStart(loggingEvent.level.colour);
183 }
184
185 function endColour(loggingEvent) {
186 return colorizeEnd(loggingEvent.level.colour);
187 }
188
189 function percent() {
190 return '%';
191 }
192
193 function pid(loggingEvent) {
194 return loggingEvent && loggingEvent.pid ? loggingEvent.pid.toString() : process.pid.toString();
195 }
196
197 function clusterInfo() {
198 // this used to try to return the master and worker pids,
199 // but it would never have worked because master pid is not available to workers
200 // leaving this here to maintain compatibility for patterns
201 return pid();
202 }
203
204 function userDefined(loggingEvent, specifier) {
205 if (typeof tokens[specifier] !== 'undefined') {
206 return typeof tokens[specifier] === 'function' ? tokens[specifier](loggingEvent) : tokens[specifier];
207 }
208
209 return null;
210 }
211
212 function contextDefined(loggingEvent, specifier) {
213 const resolver = loggingEvent.context[specifier];
214
215 if (typeof resolver !== 'undefined') {
216 return typeof resolver === 'function' ? resolver(loggingEvent) : resolver;
217 }
218
219 return null;
220 }
221
222 function fileName(loggingEvent, specifier) {
223 let filename = loggingEvent.fileName || '';
224 if (specifier) {
225 const fileDepth = parseInt(specifier, 10);
226 const fileList = filename.split(path.sep);
227 if (fileList.length > fileDepth) {
228 filename = fileList.slice(-fileDepth).join(path.sep);
229 }
230 }
231
232 return filename;
233 }
234
235 function lineNumber(loggingEvent) {
236 return loggingEvent.lineNumber ? `${loggingEvent.lineNumber}` : '';
237 }
238
239 function columnNumber(loggingEvent) {
240 return loggingEvent.columnNumber ? `${loggingEvent.columnNumber}` : '';
241 }
242
243 function callStack(loggingEvent) {
244 return loggingEvent.callStack || '';
245 }
246
247 /* eslint quote-props:0 */
248 const replacers = {
249 c: categoryName,
250 d: formatAsDate,
251 h: hostname,
252 m: formatMessage,
253 n: endOfLine,
254 p: logLevel,
255 r: startTime,
256 '[': startColour,
257 ']': endColour,
258 y: clusterInfo,
259 z: pid,
260 '%': percent,
261 x: userDefined,
262 X: contextDefined,
263 f: fileName,
264 l: lineNumber,
265 o: columnNumber,
266 s: callStack
267 };
268
269 function replaceToken(conversionCharacter, loggingEvent, specifier) {
270 return replacers[conversionCharacter](loggingEvent, specifier);
271 }
272
273 function truncate(truncation, toTruncate) {
274 let len;
275 if (truncation) {
276 len = parseInt(truncation.substr(1), 10);
277 // negative truncate length means truncate from end of string
278 return len > 0 ? toTruncate.slice(0, len) : toTruncate.slice(len);
279 }
280
281 return toTruncate;
282 }
283
284 function pad(padding, toPad) {
285 let len;
286 if (padding) {
287 if (padding.charAt(0) === '-') {
288 len = parseInt(padding.substr(1), 10);
289 // Right pad with spaces
290 while (toPad.length < len) {
291 toPad += ' ';
292 }
293 } else {
294 len = parseInt(padding, 10);
295 // Left pad with spaces
296 while (toPad.length < len) {
297 toPad = ` ${toPad}`;
298 }
299 }
300 }
301 return toPad;
302 }
303
304 function truncateAndPad(toTruncAndPad, truncation, padding) {
305 let replacement = toTruncAndPad;
306 replacement = truncate(truncation, replacement);
307 replacement = pad(padding, replacement);
308 return replacement;
309 }
310
311 return function (loggingEvent) {
312 let formattedString = '';
313 let result;
314 let searchString = pattern;
315
316 /* eslint no-cond-assign:0 */
317 while ((result = regex.exec(searchString)) !== null) {
318 // const matchedString = result[0];
319 const padding = result[1];
320 const truncation = result[2];
321 const conversionCharacter = result[3];
322 const specifier = result[5];
323 const text = result[6];
324
325 // Check if the pattern matched was just normal text
326 if (text) {
327 formattedString += text.toString();
328 } else {
329 // Create a raw replacement string based on the conversion
330 // character and specifier
331 const replacement = replaceToken(conversionCharacter, loggingEvent, specifier);
332 formattedString += truncateAndPad(replacement, truncation, padding);
333 }
334 searchString = searchString.substr(result.index + result[0].length);
335 }
336 return formattedString;
337 };
338}
339
340const layoutMakers = {
341 messagePassThrough () {
342 return messagePassThroughLayout;
343 },
344 basic () {
345 return basicLayout;
346 },
347 colored () {
348 return colouredLayout;
349 },
350 coloured () {
351 return colouredLayout;
352 },
353 pattern (config) {
354 return patternLayout(config && config.pattern, config && config.tokens);
355 },
356 dummy () {
357 return dummyLayout;
358 }
359};
360
361module.exports = {
362 basicLayout,
363 messagePassThroughLayout,
364 patternLayout,
365 colouredLayout,
366 coloredLayout: colouredLayout,
367 dummyLayout,
368 addLayout (name, serializerGenerator) {
369 layoutMakers[name] = serializerGenerator;
370 },
371 layout (name, config) {
372 return layoutMakers[name] && layoutMakers[name](config);
373 }
374};
Note: See TracBrowser for help on using the repository browser.