@foal/core
Version:
Full-featured Node.js framework, with no complexity
127 lines (126 loc) • 4.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.httpRequestMessagePrefix = void 0;
exports.formatMessage = formatMessage;
exports.shouldLog = shouldLog;
exports.httpRequestMessagePrefix = 'HTTP request - ';
function formatParamsToText(params) {
const tabLength = 2;
const offsetLength = 4;
const tab = ' '.repeat(tabLength);
const offset = ' '.repeat(offsetLength);
const lines = [];
for (const key in params) {
const value = params[key];
if (value instanceof Error) {
lines.push(`${key}: {`, `${tab}name: "${value.name}"`, `${tab}message: "${value.message}"`, `${tab}stack: ${value.stack?.split('\n').join(`\n${tab}${tab}`)}`, `}`);
continue;
}
const formattedValue = JSON.stringify(value, null, tabLength);
if (formattedValue !== undefined) {
lines.push(...`${key}: ${formattedValue}`.split('\n'));
}
}
return lines
.map(line => `\n${offset}${line}`)
.join('');
}
function formatMessageToRawText(level, message, params, now) {
const timestamp = `[${now.toISOString()}]`;
const logLevel = `[${level.toUpperCase()}]`;
return `${timestamp} ${logLevel} ${message}` + formatParamsToText(params);
}
function getColoredStatusCode(statusCode) {
if (statusCode === null) {
return 'null';
}
if (statusCode >= 500) {
return `\u001b[31m${statusCode}\u001b[39m`;
}
if (statusCode >= 400) {
return `\u001b[33m${statusCode}\u001b[39m`;
}
if (statusCode >= 300) {
return `\u001b[36m${statusCode}\u001b[39m`;
}
if (statusCode >= 200) {
return `\u001b[32m${statusCode}\u001b[39m`;
}
return `${statusCode}`;
}
function getColoredStatus(status) {
if (status === 'error') {
return `\u001b[31m${status}\u001b[39m`;
}
return `\u001b[32m${status}\u001b[39m`;
}
function formatMessageToDevText(level, message, params, now, verbose = false) {
const levelColorCodes = {
debug: 35,
info: 36,
warn: 33,
error: 31,
};
const timestamp = `\u001b[90m[${now.toLocaleTimeString()}]\u001b[39m`;
const logLevel = `\u001b[${levelColorCodes[level]}m${level.toUpperCase()}\u001b[39m`;
const consumedKeys = [];
if (message.startsWith(exports.httpRequestMessagePrefix)) {
message = message.slice(exports.httpRequestMessagePrefix.length);
message += ` ${getColoredStatusCode(params.statusCode)} - ${params.responseTime} ms`;
consumedKeys.push('method', 'url', 'statusCode', 'responseTime');
}
const socketioMessagePrefix = 'Socket.io message received - ';
if (message.startsWith(socketioMessagePrefix)) {
message = `Socket.io ${message.slice(socketioMessagePrefix.length)} ${getColoredStatus(params.status)}`;
consumedKeys.push('eventName', 'status');
}
let displayedParams = { error: params.error };
if (verbose) {
displayedParams = {};
for (const key in params) {
if (!consumedKeys.includes(key)) {
displayedParams[key] = params[key];
}
}
}
return `${timestamp} ${logLevel} ${message}` + formatParamsToText(displayedParams);
}
function formatMessageToJson(level, message, params, now) {
const json = {
timestamp: now.toISOString(),
level,
message,
...params,
};
if (json.error instanceof Error) {
json.error = {
name: json.error.name,
message: json.error.message,
stack: json.error.stack,
};
}
return JSON.stringify(json);
}
function formatMessage(level, message, params, format, now) {
switch (format) {
case 'raw':
return formatMessageToRawText(level, message, params, now);
case 'dev':
return formatMessageToDevText(level, message, params, now);
case 'dev-verbose':
return formatMessageToDevText(level, message, params, now, true);
case 'json':
return formatMessageToJson(level, message, params, now);
default:
throw new Error(`Invalid logging format: "${format}"`);
}
}
function shouldLog(level, configLogLevel) {
const levels = ['debug', 'info', 'warn', 'error'];
const levelIndex = levels.indexOf(level);
const configLogLevelIndex = levels.indexOf(configLogLevel);
if (configLogLevelIndex === -1) {
throw new Error(`Invalid log level: "${configLogLevel}"`);
}
return levelIndex >= configLogLevelIndex;
}