refactor: 改进后端工具类 - 增强日志功能和工具函数
This commit is contained in:
@@ -1,9 +1,73 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
const env = process.env.DEBUG;
|
const env = process.env.DEBUG;
|
||||||
const isDebug = env === "true";
|
const isDebug = env === "true";
|
||||||
|
|
||||||
// 日志级别枚举
|
// 日志级别枚举
|
||||||
type LogLevel = "debug" | "info" | "warn" | "error";
|
type LogLevel = "debug" | "info" | "warn" | "error";
|
||||||
|
|
||||||
|
// 日志文件路径
|
||||||
|
const logsDir = path.join(process.cwd(), 'logs');
|
||||||
|
let logFilePath: string | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Asia/Shanghai时区的格式化时间
|
||||||
|
*/
|
||||||
|
function getShanghaiTime(): Date {
|
||||||
|
const now = new Date();
|
||||||
|
const utc = now.getTime() + (now.getTimezoneOffset() * 60000);
|
||||||
|
const shanghaiOffset = 8;
|
||||||
|
return new Date(utc + (3600000 * shanghaiOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化时间为字符串
|
||||||
|
*/
|
||||||
|
function formatTimestamp(date: Date): string {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成日志文件名,处理同一天多次打开的情况
|
||||||
|
*/
|
||||||
|
function generateLogFileName(): string {
|
||||||
|
const now = getShanghaiTime();
|
||||||
|
const dateStr = now.toISOString().split('T')[0];
|
||||||
|
const timeStr = String(now.getHours()).padStart(2, '0') +
|
||||||
|
String(now.getMinutes()).padStart(2, '0') +
|
||||||
|
String(now.getSeconds()).padStart(2, '0');
|
||||||
|
return `${dateStr}_${timeStr}.log`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化日志文件
|
||||||
|
*/
|
||||||
|
function initLogFile() {
|
||||||
|
if (!fs.existsSync(logsDir)) {
|
||||||
|
fs.mkdirSync(logsDir, { recursive: true });
|
||||||
|
}
|
||||||
|
logFilePath = path.join(logsDir, generateLogFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入日志到文件
|
||||||
|
*/
|
||||||
|
function writeToFile(logMessage: string) {
|
||||||
|
if (!logFilePath) {
|
||||||
|
initLogFile();
|
||||||
|
}
|
||||||
|
if (logFilePath) {
|
||||||
|
fs.appendFileSync(logFilePath, logMessage + '\n', 'utf-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志记录器
|
* 日志记录器
|
||||||
* @param level 日志级别
|
* @param level 日志级别
|
||||||
@@ -11,24 +75,42 @@ type LogLevel = "debug" | "info" | "warn" | "error";
|
|||||||
* @param data 附加数据(可选)
|
* @param data 附加数据(可选)
|
||||||
*/
|
*/
|
||||||
function log(level: LogLevel, msg: string | Error, data?: any) {
|
function log(level: LogLevel, msg: string | Error, data?: any) {
|
||||||
const timestamp = new Date().toLocaleString();
|
const shanghaiTime = getShanghaiTime();
|
||||||
|
const timestamp = formatTimestamp(shanghaiTime);
|
||||||
const prefix = `[${level.toUpperCase()}] [${timestamp}]`;
|
const prefix = `[${level.toUpperCase()}] [${timestamp}]`;
|
||||||
|
|
||||||
// 确保只在调试模式下输出debug日志
|
// 确保只在调试模式下输出debug日志
|
||||||
if (level === "debug" && !isDebug) return;
|
if (level === "debug" && !isDebug) return;
|
||||||
|
|
||||||
|
let logMessage = '';
|
||||||
|
|
||||||
if (msg instanceof Error) {
|
if (msg instanceof Error) {
|
||||||
console.error(`${prefix} ${msg.message}`);
|
const errorMsg = `${prefix} ${msg.message}`;
|
||||||
console.error(msg.stack);
|
const stackMsg = msg.stack || '';
|
||||||
|
const dataMsg = data ? `${prefix} Data: ${JSON.stringify(data, null, 2)}` : '';
|
||||||
|
|
||||||
|
console.error(errorMsg);
|
||||||
|
console.error(stackMsg);
|
||||||
if (data) console.error(`${prefix} Data:`, data);
|
if (data) console.error(`${prefix} Data:`, data);
|
||||||
|
|
||||||
|
logMessage = errorMsg + '\n' + stackMsg;
|
||||||
|
if (data) logMessage += '\n' + dataMsg;
|
||||||
} else {
|
} else {
|
||||||
const logFunc = level === "error" ? console.error :
|
const logFunc = level === "error" ? console.error :
|
||||||
level === "warn" ? console.warn :
|
level === "warn" ? console.warn :
|
||||||
console.log;
|
console.log;
|
||||||
|
|
||||||
logFunc(`${prefix} ${msg}`);
|
const outputMsg = `${prefix} ${msg}`;
|
||||||
|
const dataMsg = data ? `${prefix} Data: ${JSON.stringify(data, null, 2)}` : '';
|
||||||
|
|
||||||
|
logFunc(outputMsg);
|
||||||
if (data) logFunc(`${prefix} Data:`, data);
|
if (data) logFunc(`${prefix} Data:`, data);
|
||||||
|
|
||||||
|
logMessage = outputMsg;
|
||||||
|
if (data) logMessage += '\n' + dataMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeToFile(logMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const logger = {
|
export const logger = {
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ export async function fastdownload(data: [string, string]|string[][]) {
|
|||||||
|
|
||||||
export async function Wfastdownload(data: string[][], ws: MessageWS) {
|
export async function Wfastdownload(data: string[][], ws: MessageWS) {
|
||||||
logger.info(`Starting web download of ${data.length} files`);
|
logger.info(`Starting web download of ${data.length} files`);
|
||||||
|
let index = 0;
|
||||||
return await pMap(
|
return await pMap(
|
||||||
data,
|
data,
|
||||||
async (item: string[], idx: number) => {
|
async (item: string[], idx: number) => {
|
||||||
@@ -214,7 +214,7 @@ export async function Wfastdownload(data: string[][], ws: MessageWS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新下载进度
|
// 更新下载进度
|
||||||
ws.download(data.length, idx + 1, filePath);
|
ws.download(data.length, ++index, filePath);
|
||||||
},
|
},
|
||||||
{ retries: 3, onFailedAttempt: (error) => {
|
{ retries: 3, onFailedAttempt: (error) => {
|
||||||
logger.warn(`Download attempt failed for ${url}, retrying (${error.attemptNumber}/3)`);
|
logger.warn(`Download attempt failed for ${url}, retrying (${error.attemptNumber}/3)`);
|
||||||
|
|||||||
Reference in New Issue
Block a user