refactor: repartition server-side and client-side code

This commit is contained in:
LIlGG
2025-10-11 18:26:07 +08:00
parent 7acc4949fb
commit e9b573a276
309 changed files with 631 additions and 962 deletions

View File

@@ -15,9 +15,82 @@ interface Logger {
setLevel: (level: DebugLevel) => void;
}
const isServer = typeof window === 'undefined';
let currentLevel: DebugLevel =
(process.env.LOG_LEVEL as DebugLevel | undefined) || (import.meta.env.DEV ? 'debug' : 'info');
let winstonLogger: any = null;
let winstonInitialized = false;
async function initializeWinston() {
if (!isServer || winstonInitialized) {
return;
}
winstonInitialized = true;
try {
const fs = await import('fs');
const path = await import('path');
const winston = await import('winston');
const { default: DailyRotateFile } = await import('winston-daily-rotate-file');
const enableFileLogging = process.env.USAGE_LOG_FILE !== 'false';
if (!enableFileLogging) {
return;
}
const logDir = path.join(process.cwd(), 'logs');
try {
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
} catch (error) {
console.error('Failed to create logs directory:', error);
return;
}
winstonLogger = winston.createLogger({
level: currentLevel,
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.printf((info) => {
const { timestamp, level, message, scope } = info;
return `${timestamp} [${level.toUpperCase()}]${scope ? ` [${scope}]` : ''}: ${message}`;
}),
),
transports: [
// 按日期分割的错误日志文件
new DailyRotateFile({
filename: path.join(logDir, 'error-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
level: 'error',
maxSize: '10m', // 10MB
maxFiles: 14, // 保留14天
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
}) as any,
// 所有级别日志
new DailyRotateFile({
filename: path.join(logDir, 'combined-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
maxSize: '20m', // 20MB
maxFiles: 7, // 保留7天
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
}) as any,
],
});
} catch (error) {
console.error('Failed to initialize Winston logger:', error);
}
}
if (isServer) {
initializeWinston();
}
export const logger: Logger = {
trace: (...messages: any[]) => log('trace', undefined, messages),
debug: (...messages: any[]) => log('debug', undefined, messages),
@@ -44,6 +117,11 @@ function setLevel(level: DebugLevel) {
}
currentLevel = level;
// 更新 Winston logger 级别
if (winstonLogger) {
winstonLogger.level = level;
}
}
function log(level: DebugLevel, scope: string | undefined, messages: any[]) {
@@ -53,41 +131,68 @@ function log(level: DebugLevel, scope: string | undefined, messages: any[]) {
return;
}
const allMessages = messages.reduce((acc, current) => {
if (acc.endsWith('\n')) {
return acc + current;
}
if (!acc) {
return current;
}
return `${acc} ${current}`;
}, '');
const labelBackgroundColor = getColorForLevel(level);
const labelTextColor = level === 'warn' ? '#000000' : '#FFFFFF';
const labelStyles = getLabelStyles(labelBackgroundColor, labelTextColor);
const scopeStyles = getLabelStyles('#77828D', 'white');
const styles = [labelStyles];
if (typeof scope === 'string') {
styles.push('', scopeStyles);
}
let labelText = formatText(` ${level.toUpperCase()} `, labelTextColor, labelBackgroundColor);
if (scope) {
labelText = `${labelText} ${formatText(` ${scope} `, '#FFFFFF', '77828D')}`;
}
// 控制台日志
// 控制台日志 - 根据环境使用不同格式
if (typeof window !== 'undefined') {
console.log(`%c${level.toUpperCase()}${scope ? `%c %c${scope}` : ''}`, ...styles, allMessages);
// 浏览器环境 - 保持对象原样,利用浏览器的原生格式化
const labelStyles = getLabelStyles(labelBackgroundColor, labelTextColor);
const scopeStyles = getLabelStyles('#77828D', 'white');
const styles = [labelStyles];
if (typeof scope === 'string') {
styles.push('', scopeStyles);
}
// 直接传递原始消息,浏览器会自动格式化对象
console.log(`%c${level.toUpperCase()}${scope ? `%c %c${scope}` : ''}`, ...styles, ...messages);
} else {
// Node.js 环境 - 将对象格式化为 JSON 字符串
const formattedMessages = messages.map((msg) => {
if (typeof msg === 'object' && msg !== null) {
try {
return JSON.stringify(msg, null, 2);
} catch {
return String(msg);
}
}
return msg;
});
const allMessages = formattedMessages.reduce((acc, current) => {
if (acc.endsWith('\n')) {
return acc + current;
}
if (!acc) {
return current;
}
return `${acc} ${current}`;
}, '');
let labelText = formatText(` ${level.toUpperCase()} `, labelTextColor, labelBackgroundColor);
if (scope) {
labelText = `${labelText} ${formatText(` ${scope} `, '#FFFFFF', '77828D')}`;
}
console.log(`${labelText}`, allMessages);
// 写入文件日志(仅服务端)
if (winstonLogger) {
try {
winstonLogger.log({
level,
message: allMessages,
scope,
});
} catch (error) {
console.error('Failed to write to log file:', error);
}
}
}
}