日志显示更新

This commit is contained in:
2025-09-27 16:18:43 +08:00
parent 038d325e9d
commit 617a361713
7 changed files with 94 additions and 77 deletions
+46 -28
View File
@@ -3,6 +3,33 @@
*/ */
const { defaultLogger } = require('../utils/logger'); const { defaultLogger } = require('../utils/logger');
// 颜色常量
const METHOD_COLORS = {
GET: '\x1b[32m', // 绿色
POST: '\x1b[34m', // 蓝色
PUT: '\x1b[33m', // 黄色
DELETE: '\x1b[31m', // 红色
PATCH: '\x1b[35m', // 紫色
DEFAULT: '\x1b[37m' // 白色
};
// 状态码颜色
const STATUS_COLORS = {
SUCCESS: '\x1b[32m', // 2xx - 绿色
REDIRECT: '\x1b[36m', // 3xx - 青色
CLIENT_ERROR: '\x1b[33m', // 4xx - 黄色
SERVER_ERROR: '\x1b[31m' // 5xx - 红色
};
// 响应时间颜色
const DURATION_COLORS = {
FAST: '\x1b[32m', // < 100ms - 绿色
MEDIUM: '\x1b[33m', // < 500ms - 黄色
SLOW: '\x1b[31m' // >= 500ms - 红色
};
const RESET_COLOR = '\x1b[0m';
// 创建logger实例 // 创建logger实例
const logger = defaultLogger.child('API'); const logger = defaultLogger.child('API');
@@ -58,42 +85,33 @@ function loggerMiddleware(req, res, next) {
const method = req.method; const method = req.method;
const url = req.originalUrl; const url = req.originalUrl;
// 根据状态码选择图标 // 获取方法颜色
let statusIcon; const methodColor = METHOD_COLORS[method] || METHOD_COLORS.DEFAULT;
// 获取状态码颜色
let statusColor;
if (statusCode >= 200 && statusCode < 300) { if (statusCode >= 200 && statusCode < 300) {
statusIcon = '✅'; statusColor = STATUS_COLORS.SUCCESS;
} else if (statusCode >= 300 && statusCode < 400) { } else if (statusCode >= 300 && statusCode < 400) {
statusIcon = '🔄'; statusColor = STATUS_COLORS.REDIRECT;
} else if (statusCode >= 400 && statusCode < 500) { } else if (statusCode >= 400 && statusCode < 500) {
statusIcon = '⚠️'; statusColor = STATUS_COLORS.CLIENT_ERROR;
} else { } else {
statusIcon = '❌'; statusColor = STATUS_COLORS.SERVER_ERROR;
} }
// 根据请求类型选择图标 // 获取响应时间颜色
let methodIcon; let durationColor;
switch (method) { if (duration < 100) {
case 'GET': durationColor = DURATION_COLORS.FAST;
methodIcon = '📥'; } else if (duration < 500) {
break; durationColor = DURATION_COLORS.MEDIUM;
case 'POST': } else {
methodIcon = '📤'; durationColor = DURATION_COLORS.SLOW;
break;
case 'PUT':
methodIcon = '🔄';
break;
case 'DELETE':
methodIcon = '🗑️';
break;
case 'PATCH':
methodIcon = '🔧';
break;
default:
methodIcon = '❓';
} }
// 输出日志 // 输出彩色日志
logger.info(`${statusIcon} ${methodIcon} ${method} ${url} ${statusCode} ${duration}ms`); logger.info(`${methodColor}[${method}]${RESET_COLOR} ${url} ${statusColor}${statusCode}${RESET_COLOR} ${durationColor}${duration}ms${RESET_COLOR}`);
// 调用原始的end方法 // 调用原始的end方法
originalEnd.call(this, chunk, encoding); originalEnd.call(this, chunk, encoding);
+9 -9
View File
@@ -34,7 +34,7 @@ class PixivServer {
* 初始化服务器 * 初始化服务器
*/ */
async init() { async init() {
logger.info('🔧 正在初始化 Pixiv 后端服务器...'); logger.info('正在初始化 Pixiv 后端服务器...');
// 重新设置端口(从环境变量获取) // 重新设置端口(从环境变量获取)
this.port = process.env.PORT || 3000; this.port = process.env.PORT || 3000;
@@ -55,7 +55,7 @@ class PixivServer {
// 配置错误处理 // 配置错误处理
this.setupErrorHandling(); this.setupErrorHandling();
logger.info('服务器初始化完成'); logger.info('服务器初始化完成');
} }
/** /**
@@ -99,12 +99,12 @@ class PixivServer {
*/ */
start() { start() {
this.app.listen(this.port, () => { this.app.listen(this.port, () => {
logger.info('Pixiv 后端服务器已启动'); logger.info('Pixiv 后端服务器已启动');
logger.info(`📍 服务地址: http://localhost:${this.port}`); logger.info(`服务地址: http://localhost:${this.port}`);
logger.info(`🔗 健康检查: http://localhost:${this.port}/health`); logger.info(`健康检查: http://localhost:${this.port}/health`);
logger.info(`📊 登录状态: ${this.backend.isLoggedIn ? '已登录' : '未登录'}`); logger.info(`登录状态: ${this.backend.isLoggedIn ? '已登录' : '未登录'}`);
if (this.backend.isLoggedIn) { if (this.backend.isLoggedIn) {
logger.info(`👤 用户: ${this.backend.config.user?.account}`); logger.info(`用户: ${this.backend.config.user?.account}`);
} }
logger.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); logger.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
}); });
@@ -114,10 +114,10 @@ class PixivServer {
* 优雅关闭 * 优雅关闭
*/ */
async shutdown() { async shutdown() {
logger.info('🔄 正在关闭服务器...'); logger.info('正在关闭服务器...');
// 清理代理环境变量 // 清理代理环境变量
proxyConfig.clearEnvironmentVariables(); proxyConfig.clearEnvironmentVariables();
logger.info('服务器已关闭'); logger.info('服务器已关闭');
process.exit(0); process.exit(0);
} }
} }
+1 -1
View File
@@ -90,7 +90,7 @@ class ImageCacheService {
async ensureCacheDir() { async ensureCacheDir() {
try { try {
await fs.mkdir(this.cacheDir, { recursive: true }); await fs.mkdir(this.cacheDir, { recursive: true });
logger.info('图片缓存目录创建成功', { cacheDir: this.cacheDir }); logger.info('图片缓存目录创建成功');
} catch (error) { } catch (error) {
logger.error('创建图片缓存目录失败', error); logger.error('创建图片缓存目录失败', error);
} }
+13 -13
View File
@@ -64,49 +64,49 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development';
// 如果提供了代理端口,设置环境变量 // 如果提供了代理端口,设置环境变量
if (cliOptions.proxyPort) { if (cliOptions.proxyPort) {
process.env.PROXY_PORT = cliOptions.proxyPort.toString(); process.env.PROXY_PORT = cliOptions.proxyPort.toString();
logger.info(`📡 代理端口已设置为: ${cliOptions.proxyPort}`); logger.info(`代理端口已设置为: ${cliOptions.proxyPort}`);
} }
// 如果提供了服务器端口,设置环境变量 // 如果提供了服务器端口,设置环境变量
if (cliOptions.serverPort) { if (cliOptions.serverPort) {
process.env.PORT = cliOptions.serverPort.toString(); process.env.PORT = cliOptions.serverPort.toString();
logger.info(`🌐 服务器端口已设置为: ${cliOptions.serverPort}`); logger.info(`服务器端口已设置为: ${cliOptions.serverPort}`);
} }
logger.info('🚀 启动 Pixiv 后端服务器...'); logger.info('启动 Pixiv 后端服务器...');
// 创建服务器实例 // 创建服务器实例
const server = new PixivServer(); const server = new PixivServer();
// 处理进程信号 // 处理进程信号
process.on('SIGINT', async () => { process.on('SIGINT', async () => {
logger.info('🛑 收到 SIGINT 信号,正在关闭服务器...'); logger.info('收到 SIGINT 信号,正在关闭服务器...');
await server.shutdown(); await server.shutdown();
}); });
process.on('SIGTERM', async () => { process.on('SIGTERM', async () => {
logger.info('🛑 收到 SIGTERM 信号,正在关闭服务器...'); logger.info('收到 SIGTERM 信号,正在关闭服务器...');
await server.shutdown(); await server.shutdown();
}); });
// 处理未捕获的异常 // 处理未捕获的异常
process.on('uncaughtException', error => { process.on('uncaughtException', error => {
logger.error('未捕获的异常', error); logger.error('未捕获的异常', error);
logger.error('异常堆栈:', error.stack); logger.error('异常堆栈:', error.stack);
process.exit(1); process.exit(1);
}); });
process.on('unhandledRejection', (reason, promise) => { process.on('unhandledRejection', (reason, promise) => {
logger.error('未处理的 Promise 拒绝'); logger.error('未处理的 Promise 拒绝');
logger.error('拒绝原因:', reason); logger.error('拒绝原因:', reason);
if (reason instanceof Error) { if (reason instanceof Error) {
logger.error('错误堆栈:', reason.stack); logger.error('错误堆栈:', reason.stack);
} }
logger.error('Promise:', promise); logger.error('Promise:', promise);
// 不要立即退出进程,而是记录错误并继续运行 // 不要立即退出进程,而是记录错误并继续运行
// 这样可以避免因为自动恢复任务的小错误而停止整个服务 // 这样可以避免因为自动恢复任务的小错误而停止整个服务
logger.warn('⚠️ 继续运行服务器,但建议检查上述错误'); logger.warn('继续运行服务器,但建议检查上述错误');
}); });
// 启动服务器 // 启动服务器
@@ -114,6 +114,6 @@ server
.init() .init()
.then(() => server.start()) .then(() => server.start())
.catch(error => { .catch(error => {
logger.error('服务器启动失败', error); logger.error('服务器启动失败', error);
process.exit(1); process.exit(1);
}); });
+10 -11
View File
@@ -39,6 +39,7 @@ const LogLevelColors = {
*/ */
const ModuleColors = { const ModuleColors = {
'Server': '\x1b[32m', // 绿色 'Server': '\x1b[32m', // 绿色
'API': '\x1b[32m', // 绿色
'Start': '\x1b[34m', // 蓝色 'Start': '\x1b[34m', // 蓝色
'PixivBackend': '\x1b[35m', // 紫色 'PixivBackend': '\x1b[35m', // 紫色
'PixivAuth': '\x1b[36m', // 青色 'PixivAuth': '\x1b[36m', // 青色
@@ -51,7 +52,6 @@ const ModuleColors = {
'Artist': '\x1b[92m', // 亮绿色 'Artist': '\x1b[92m', // 亮绿色
'Repository': '\x1b[94m', // 亮蓝色 'Repository': '\x1b[94m', // 亮蓝色
'ErrorHandler': '\x1b[91m', // 亮红色 'ErrorHandler': '\x1b[91m', // 亮红色
'API': '\x1b[97m', // 亮白色
'FileManager': '\x1b[98m', // 亮青色 'FileManager': '\x1b[98m', // 亮青色
'ProgressManager': '\x1b[99m', // 亮紫色 'ProgressManager': '\x1b[99m', // 亮紫色
'Default': '\x1b[39m' // 默认颜色 'Default': '\x1b[39m' // 默认颜色
@@ -63,14 +63,14 @@ const ModuleColors = {
const RESET_COLOR = '\x1b[0m'; const RESET_COLOR = '\x1b[0m';
/** /**
* 日志图标映射 * 日志级别文本映射
*/ */
const LogLevelIcons = { const LogLevelTexts = {
[LogLevel.ERROR]: '', [LogLevel.ERROR]: 'ERROR',
[LogLevel.WARN]: '⚠️', [LogLevel.WARN]: 'WARN',
[LogLevel.INFO]: '', [LogLevel.INFO]: 'INFO',
[LogLevel.DEBUG]: '🔧', [LogLevel.DEBUG]: 'DEBUG',
[LogLevel.TRACE]: '🔍' [LogLevel.TRACE]: 'TRACE'
}; };
class Logger { class Logger {
@@ -143,10 +143,9 @@ class Logger {
*/ */
formatMessage(level, message, data = null) { formatMessage(level, message, data = null) {
const timeStr = this.getTimeString(); const timeStr = this.getTimeString();
const levelName = LogLevelNames[level]; const levelName = LogLevelTexts[level];
const icon = LogLevelIcons[level];
let formattedMessage = `[${timeStr}] [${levelName}] [${this.module}] ${icon} ${message}`; let formattedMessage = `[${timeStr}] [${levelName}] [${this.module}] ${message}`;
if (data !== null && data !== undefined) { if (data !== null && data !== undefined) {
if (typeof data === 'object') { if (typeof data === 'object') {
+4 -4
View File
@@ -95,12 +95,12 @@ pause
await fs.ensureDir(path.join(portableDir, 'data')); await fs.ensureDir(path.join(portableDir, 'data'));
await fs.ensureDir(path.join(portableDir, 'downloads')); await fs.ensureDir(path.join(portableDir, 'downloads'));
logger.info('便携版创建完成!'); logger.info('便携版创建完成!');
logger.info(`📁 位置: ${portableDir}`); logger.info(`位置: ${portableDir}`);
logger.info('📦 可以将整个文件夹打包分发给用户'); logger.info('可以将整个文件夹打包分发给用户');
} catch (error) { } catch (error) {
logger.error('创建便携版失败', error); logger.error('创建便携版失败', error);
} }
} }
+8 -8
View File
@@ -13,20 +13,20 @@ set PROXY_PORT=
set SERVER_PORT=3000 set SERVER_PORT=3000
echo. echo.
echo 🚀 Pixiv Manager 启动中... echo Pixiv Manager 启动中...
echo. echo.
cd /d "%~dp0" cd /d "%~dp0"
echo 📡 当前代理端口: %PROXY_PORT% echo 当前代理端口: %PROXY_PORT%
echo 🌐 当前服务器端口: %SERVER_PORT% echo 当前服务器端口: %SERVER_PORT%
echo 💡 如需修改端口,请用记事本打开此文件,修改对应的端口号 echo 如需修改端口,请用记事本打开此文件,修改对应的端口号
echo. echo.
echo 📊 启动后端服务器... echo 启动后端服务器...
echo 🌐 访问地址: http://localhost:%SERVER_PORT% echo 访问地址: http://localhost:%SERVER_PORT%
echo. echo.
echo 💡 提示: 按 Ctrl+C 停止服务器 echo 提示: 按 Ctrl+C 停止服务器
echo. echo.
:: 启动服务器并传递代理端口和服务器端口 :: 启动服务器并传递代理端口和服务器端口
@@ -37,5 +37,5 @@ if "%PROXY_PORT%"=="" (
) )
echo. echo.
echo ⏹️ 服务器已停止 echo 服务器已停止
pause pause