mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-06 22:19:25 +08:00
177 lines
4.2 KiB
TypeScript
177 lines
4.2 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import chalk from 'chalk';
|
|
import winston from 'winston';
|
|
import { getLoggerFormat } from './config';
|
|
import { LoggerOptions } from './logger';
|
|
import { isEmpty } from 'lodash';
|
|
|
|
const DEFAULT_DELIMITER = '|';
|
|
|
|
const colorize = {};
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
|
|
export const getFormat = (format?: LoggerOptions['format']) => {
|
|
const configFormat = format || getLoggerFormat();
|
|
let logFormat: winston.Logform.Format;
|
|
switch (configFormat) {
|
|
case 'console':
|
|
logFormat = winston.format.combine(consoleFormat);
|
|
break;
|
|
case 'logfmt':
|
|
logFormat = logfmtFormat;
|
|
break;
|
|
case 'delimiter':
|
|
logFormat = winston.format.combine(escapeFormat, delimiterFormat);
|
|
break;
|
|
case 'json':
|
|
logFormat = winston.format.combine(winston.format.json({ deterministic: false }));
|
|
break;
|
|
default:
|
|
return winston.format.combine(format as winston.Logform.Format);
|
|
}
|
|
return winston.format.combine(sortFormat, logFormat);
|
|
};
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export const colorFormat: winston.Logform.Format = winston.format((info) => {
|
|
Object.entries(info).forEach(([k, v]) => {
|
|
const level = info['level'];
|
|
if (colorize[k]) {
|
|
info[k] = colorize[k](v);
|
|
return;
|
|
}
|
|
if (colorize[level]?.[k]) {
|
|
info[k] = colorize[level][k](v);
|
|
return;
|
|
}
|
|
});
|
|
return info;
|
|
})();
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export const stripColorFormat: winston.Logform.Format = winston.format((info) => {
|
|
Object.entries(info).forEach(([k, v]) => {
|
|
if (typeof v !== 'string') {
|
|
return;
|
|
}
|
|
const regex = new RegExp(`\\x1b\\[\\d+m`, 'g');
|
|
info[k] = v.replace(regex, '');
|
|
});
|
|
return info;
|
|
})();
|
|
|
|
/**
|
|
* @internal
|
|
*https://brandur.org/logfmt
|
|
*/
|
|
export const logfmtFormat: winston.Logform.Format = winston.format.printf((info) =>
|
|
Object.entries(info)
|
|
.map(([k, v]) => {
|
|
if (typeof v === 'object') {
|
|
try {
|
|
v = JSON.stringify(v);
|
|
} catch (error) {
|
|
v = String(v);
|
|
}
|
|
}
|
|
if (v === undefined || v === null) {
|
|
v = '';
|
|
}
|
|
return `${k}=${v}`;
|
|
})
|
|
.join(' '),
|
|
);
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export const consoleFormat: winston.Logform.Format = winston.format.printf((info) => {
|
|
const keys = ['level', 'timestamp', 'message'];
|
|
Object.entries(info).forEach(([k, v]) => {
|
|
if (typeof v === 'object') {
|
|
if (isEmpty(v)) {
|
|
info[k] = '';
|
|
return;
|
|
}
|
|
try {
|
|
info[k] = JSON.stringify(v);
|
|
} catch (error) {
|
|
info[k] = String(v);
|
|
}
|
|
}
|
|
if (v === undefined || v === null) {
|
|
info[k] = '';
|
|
}
|
|
});
|
|
|
|
const tags = Object.entries(info)
|
|
.filter(([k, v]) => !keys.includes(k) && v)
|
|
.map(([k, v]) => `${k}=${v}`)
|
|
.join(' ');
|
|
|
|
const level = `[${info.level}]`.padEnd(7, ' ');
|
|
const message = info.message.padEnd(44, ' ');
|
|
const color =
|
|
{
|
|
error: chalk.red,
|
|
warn: chalk.yellow,
|
|
info: chalk.green,
|
|
debug: chalk.blue,
|
|
trace: chalk.cyan,
|
|
}[info.level] || chalk.white;
|
|
const colorized = message.startsWith('Executing')
|
|
? color(`${info.timestamp} ${level}`) + ` ${message}`
|
|
: color(`${info.timestamp} ${level} ${message}`);
|
|
return `${colorized} ${tags}`;
|
|
});
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export const delimiterFormat = winston.format.printf((info) =>
|
|
Object.entries(info)
|
|
.map(([, v]) => {
|
|
if (typeof v === 'object') {
|
|
try {
|
|
return JSON.stringify(v);
|
|
} catch (error) {
|
|
return String(v);
|
|
}
|
|
}
|
|
return v;
|
|
})
|
|
.join(DEFAULT_DELIMITER),
|
|
);
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export const escapeFormat: winston.Logform.Format = winston.format((info) => {
|
|
let { message } = info;
|
|
if (typeof message === 'string' && message.includes(DEFAULT_DELIMITER)) {
|
|
message = message.replace(/"/g, '\\"');
|
|
message = `"${message}"`;
|
|
}
|
|
return { ...info, message };
|
|
})();
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export const sortFormat = winston.format((info) => ({ level: info.level, ...info }))();
|