1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | const path = require('path');
|
13 | const fs = require('fs-extra');
|
14 | const chalk = require('chalk');
|
15 | const {
|
16 | SimpleInterface,
|
17 | rootLogger,
|
18 | serializeMessage,
|
19 | messageFormatJsonString,
|
20 | messageFormatTechnical,
|
21 | MultiLogger,
|
22 | FileLogger,
|
23 | ConsoleLogger,
|
24 | } = require('@adobe/helix-log');
|
25 |
|
26 | const colors = {
|
27 | info: 'green',
|
28 | warn: 'yellow',
|
29 | error: 'red',
|
30 | };
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | const suppressProgress = (fields) => {
|
37 |
|
38 | if (fields.progress && console._stderr.isTTY) {
|
39 | return undefined;
|
40 | }
|
41 |
|
42 | delete fields.progress;
|
43 | return fields;
|
44 | };
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | const filterProgress = (fields) => {
|
50 |
|
51 | delete fields.progress;
|
52 | return fields;
|
53 | };
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | const categoryAwareMessageFormatConsole = (fields) => {
|
60 |
|
61 | const {level, timestamp, message, category = 'cli', ...rest} = fields;
|
62 |
|
63 | const fullMsg = Object.keys(rest).length === 0 ? message : [...message, ' ', rest];
|
64 | const ser = serializeMessage(fullMsg, { colors: false });
|
65 |
|
66 | let lvl = level.toLowerCase();
|
67 | if (colors[level]) {
|
68 | lvl = chalk[colors[level]](lvl);
|
69 | }
|
70 | if (category === 'cli') {
|
71 | if (level === 'info') {
|
72 | return `${ser}`;
|
73 | } else {
|
74 | return `${lvl}: ${ser}`;
|
75 | }
|
76 | } else {
|
77 | return chalk`{grey [${category}]} ${lvl}: ${ser}`;
|
78 | }
|
79 | };
|
80 |
|
81 |
|
82 | rootLogger.loggers.get('default').formatter = categoryAwareMessageFormatConsole;
|
83 |
|
84 |
|
85 | const loggersByCategory = new Map();
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | function getOrCreateLogger(config = 'cli') {
|
98 | let categ;
|
99 | if (typeof config === 'string') {
|
100 | categ = config;
|
101 | } else {
|
102 | categ = (config && config.category) || 'cli';
|
103 | }
|
104 |
|
105 | if (loggersByCategory.has(categ)) {
|
106 | return loggersByCategory.get(categ);
|
107 | }
|
108 |
|
109 |
|
110 | const level = (config && config.logLevel) || 'info';
|
111 | const logsDir = path.normalize((config && config.logsDir) || 'logs');
|
112 | const logFiles = config && Array.isArray(config.logFile)
|
113 | ? config.logFile
|
114 | : ['-', (config && config.logFile) || path.join(logsDir, `${categ}-server.log`)];
|
115 |
|
116 | const loggers = new Map();
|
117 | logFiles.forEach((logFile) => {
|
118 | const name = loggers.has('default') ? logFile : 'default';
|
119 | if (logFile === '-') {
|
120 | loggers.set(name, new ConsoleLogger({
|
121 | filter: categ === 'cli' ? suppressProgress : filterProgress,
|
122 | level,
|
123 | formatter: categoryAwareMessageFormatConsole,
|
124 | }));
|
125 | } else {
|
126 | fs.ensureDirSync(path.dirname(logFile));
|
127 | loggers.set(name, new FileLogger(logFile, {
|
128 | level: 'debug',
|
129 | formatter: /\.json/.test(logFile) ? messageFormatJsonString : messageFormatTechnical,
|
130 | }));
|
131 | }
|
132 | });
|
133 |
|
134 |
|
135 | const log = new SimpleInterface({
|
136 | level,
|
137 | defaultFields: {
|
138 | category: categ,
|
139 | },
|
140 | logger: new MultiLogger(loggers),
|
141 | });
|
142 |
|
143 | loggersByCategory.set(categ, log);
|
144 | return log;
|
145 | }
|
146 |
|
147 | module.exports = {
|
148 | getOrCreateLogger,
|
149 | };
|