UNPKG

9.15 kBJavaScriptView Raw
1"use strict";
2var ConsoleLogger_1;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.ConsoleLogger = void 0;
5const tslib_1 = require("tslib");
6const core_1 = require("../decorators/core");
7const cli_colors_util_1 = require("../utils/cli-colors.util");
8const shared_utils_1 = require("../utils/shared.utils");
9const utils_1 = require("./utils");
10const DEFAULT_LOG_LEVELS = [
11 'log',
12 'error',
13 'warn',
14 'debug',
15 'verbose',
16 'fatal',
17];
18const dateTimeFormatter = new Intl.DateTimeFormat(undefined, {
19 year: 'numeric',
20 hour: 'numeric',
21 minute: 'numeric',
22 second: 'numeric',
23 day: '2-digit',
24 month: '2-digit',
25});
26let ConsoleLogger = ConsoleLogger_1 = class ConsoleLogger {
27 constructor(context, options = {}) {
28 this.context = context;
29 this.options = options;
30 if (!options.logLevels) {
31 options.logLevels = DEFAULT_LOG_LEVELS;
32 }
33 if (context) {
34 this.originalContext = context;
35 }
36 }
37 log(message, ...optionalParams) {
38 if (!this.isLevelEnabled('log')) {
39 return;
40 }
41 const { messages, context } = this.getContextAndMessagesToPrint([
42 message,
43 ...optionalParams,
44 ]);
45 this.printMessages(messages, context, 'log');
46 }
47 error(message, ...optionalParams) {
48 if (!this.isLevelEnabled('error')) {
49 return;
50 }
51 const { messages, context, stack } = this.getContextAndStackAndMessagesToPrint([message, ...optionalParams]);
52 this.printMessages(messages, context, 'error', 'stderr');
53 this.printStackTrace(stack);
54 }
55 warn(message, ...optionalParams) {
56 if (!this.isLevelEnabled('warn')) {
57 return;
58 }
59 const { messages, context } = this.getContextAndMessagesToPrint([
60 message,
61 ...optionalParams,
62 ]);
63 this.printMessages(messages, context, 'warn');
64 }
65 debug(message, ...optionalParams) {
66 if (!this.isLevelEnabled('debug')) {
67 return;
68 }
69 const { messages, context } = this.getContextAndMessagesToPrint([
70 message,
71 ...optionalParams,
72 ]);
73 this.printMessages(messages, context, 'debug');
74 }
75 verbose(message, ...optionalParams) {
76 if (!this.isLevelEnabled('verbose')) {
77 return;
78 }
79 const { messages, context } = this.getContextAndMessagesToPrint([
80 message,
81 ...optionalParams,
82 ]);
83 this.printMessages(messages, context, 'verbose');
84 }
85 fatal(message, ...optionalParams) {
86 if (!this.isLevelEnabled('fatal')) {
87 return;
88 }
89 const { messages, context } = this.getContextAndMessagesToPrint([
90 message,
91 ...optionalParams,
92 ]);
93 this.printMessages(messages, context, 'fatal');
94 }
95 /**
96 * Set log levels
97 * @param levels log levels
98 */
99 setLogLevels(levels) {
100 if (!this.options) {
101 this.options = {};
102 }
103 this.options.logLevels = levels;
104 }
105 /**
106 * Set logger context
107 * @param context context
108 */
109 setContext(context) {
110 this.context = context;
111 }
112 /**
113 * Resets the logger context to the value that was passed in the constructor.
114 */
115 resetContext() {
116 this.context = this.originalContext;
117 }
118 isLevelEnabled(level) {
119 const logLevels = this.options?.logLevels;
120 return (0, utils_1.isLogLevelEnabled)(level, logLevels);
121 }
122 getTimestamp() {
123 return dateTimeFormatter.format(Date.now());
124 }
125 printMessages(messages, context = '', logLevel = 'log', writeStreamType) {
126 messages.forEach(message => {
127 const pidMessage = this.formatPid(process.pid);
128 const contextMessage = this.formatContext(context);
129 const timestampDiff = this.updateAndGetTimestampDiff();
130 const formattedLogLevel = logLevel.toUpperCase().padStart(7, ' ');
131 const formattedMessage = this.formatMessage(logLevel, message, pidMessage, formattedLogLevel, contextMessage, timestampDiff);
132 process[writeStreamType ?? 'stdout'].write(formattedMessage);
133 });
134 }
135 formatPid(pid) {
136 return `[Nest] ${pid} - `;
137 }
138 formatContext(context) {
139 return context ? (0, cli_colors_util_1.yellow)(`[${context}] `) : '';
140 }
141 formatMessage(logLevel, message, pidMessage, formattedLogLevel, contextMessage, timestampDiff) {
142 const output = this.stringifyMessage(message, logLevel);
143 pidMessage = this.colorize(pidMessage, logLevel);
144 formattedLogLevel = this.colorize(formattedLogLevel, logLevel);
145 return `${pidMessage}${this.getTimestamp()} ${formattedLogLevel} ${contextMessage}${output}${timestampDiff}\n`;
146 }
147 stringifyMessage(message, logLevel) {
148 if ((0, shared_utils_1.isFunction)(message)) {
149 const messageAsStr = Function.prototype.toString.call(message);
150 const isClass = messageAsStr.startsWith('class ');
151 if (isClass) {
152 // If the message is a class, we will display the class name.
153 return this.stringifyMessage(message.name, logLevel);
154 }
155 // If the message is a non-class function, call it and re-resolve its value.
156 return this.stringifyMessage(message(), logLevel);
157 }
158 return (0, shared_utils_1.isPlainObject)(message) || Array.isArray(message)
159 ? `${this.colorize('Object:', logLevel)}\n${JSON.stringify(message, (key, value) => typeof value === 'bigint' ? value.toString() : value, 2)}\n`
160 : this.colorize(message, logLevel);
161 }
162 colorize(message, logLevel) {
163 const color = this.getColorByLogLevel(logLevel);
164 return color(message);
165 }
166 printStackTrace(stack) {
167 if (!stack) {
168 return;
169 }
170 process.stderr.write(`${stack}\n`);
171 }
172 updateAndGetTimestampDiff() {
173 const includeTimestamp = ConsoleLogger_1.lastTimestampAt && this.options?.timestamp;
174 const result = includeTimestamp
175 ? this.formatTimestampDiff(Date.now() - ConsoleLogger_1.lastTimestampAt)
176 : '';
177 ConsoleLogger_1.lastTimestampAt = Date.now();
178 return result;
179 }
180 formatTimestampDiff(timestampDiff) {
181 return (0, cli_colors_util_1.yellow)(` +${timestampDiff}ms`);
182 }
183 getContextAndMessagesToPrint(args) {
184 if (args?.length <= 1) {
185 return { messages: args, context: this.context };
186 }
187 const lastElement = args[args.length - 1];
188 const isContext = (0, shared_utils_1.isString)(lastElement);
189 if (!isContext) {
190 return { messages: args, context: this.context };
191 }
192 return {
193 context: lastElement,
194 messages: args.slice(0, args.length - 1),
195 };
196 }
197 getContextAndStackAndMessagesToPrint(args) {
198 if (args.length === 2) {
199 return this.isStackFormat(args[1])
200 ? {
201 messages: [args[0]],
202 stack: args[1],
203 context: this.context,
204 }
205 : {
206 messages: [args[0]],
207 context: args[1],
208 };
209 }
210 const { messages, context } = this.getContextAndMessagesToPrint(args);
211 if (messages?.length <= 1) {
212 return { messages, context };
213 }
214 const lastElement = messages[messages.length - 1];
215 const isStack = (0, shared_utils_1.isString)(lastElement);
216 // https://github.com/nestjs/nest/issues/11074#issuecomment-1421680060
217 if (!isStack && !(0, shared_utils_1.isUndefined)(lastElement)) {
218 return { messages, context };
219 }
220 return {
221 stack: lastElement,
222 messages: messages.slice(0, messages.length - 1),
223 context,
224 };
225 }
226 isStackFormat(stack) {
227 if (!(0, shared_utils_1.isString)(stack) && !(0, shared_utils_1.isUndefined)(stack)) {
228 return false;
229 }
230 return /^(.)+\n\s+at .+:\d+:\d+/.test(stack);
231 }
232 getColorByLogLevel(level) {
233 switch (level) {
234 case 'debug':
235 return cli_colors_util_1.clc.magentaBright;
236 case 'warn':
237 return cli_colors_util_1.clc.yellow;
238 case 'error':
239 return cli_colors_util_1.clc.red;
240 case 'verbose':
241 return cli_colors_util_1.clc.cyanBright;
242 case 'fatal':
243 return cli_colors_util_1.clc.bold;
244 default:
245 return cli_colors_util_1.clc.green;
246 }
247 }
248};
249exports.ConsoleLogger = ConsoleLogger;
250exports.ConsoleLogger = ConsoleLogger = ConsoleLogger_1 = tslib_1.__decorate([
251 (0, core_1.Injectable)(),
252 tslib_1.__param(0, (0, core_1.Optional)()),
253 tslib_1.__param(1, (0, core_1.Optional)()),
254 tslib_1.__metadata("design:paramtypes", [String, Object])
255], ConsoleLogger);