feat: 全面升级系统日志和反爬虫功能

- 新增专业日志系统:集成 Winston 日志框架,支持按天轮转和分级存储
- 增强反爬虫能力:集成 puppeteer-extra-plugin-stealth 插件,提升隐蔽性
- 新增独立爬虫脚本:可通过 npm run crawl 命令单独执行爬虫任务
- 优化前端日期筛选:添加日期范围选择器,支持3天/7天快速筛选
- 改进爬虫统计功能:详细记录每个平台的成功/失败情况和执行时间
- 移除默认关键词初始化:避免重复创建预设关键词
- 扩展环境配置:新增 LOG_LEVEL 日志级别配置选项
- 增强.gitignore:添加日志目录、构建产物等忽略规则
- 升级执行时间限制:将最大执行时间从1小时延长至3小时
- 完善错误处理:更好的异常捕获和日志记录机制
This commit is contained in:
dmy
2026-01-12 10:46:10 +08:00
parent 66f535ed0c
commit 3e6456e120
14 changed files with 495 additions and 119 deletions

View File

@@ -0,0 +1,9 @@
import { Module, Global } from '@nestjs/common';
import { CustomLogger } from './logger.service';
@Global()
@Module({
providers: [CustomLogger],
exports: [CustomLogger],
})
export class LoggerModule {}

View File

@@ -0,0 +1,31 @@
import { Injectable, LoggerService, Scope } from '@nestjs/common';
import { winstonLogger } from './winston.config';
@Injectable({ scope: Scope.TRANSIENT })
export class CustomLogger implements LoggerService {
private context?: string;
setContext(context: string) {
this.context = context;
}
log(message: any, context?: string) {
winstonLogger.info(message, { context: context || this.context });
}
error(message: any, trace?: string, context?: string) {
winstonLogger.error(message, { context: context || this.context, trace });
}
warn(message: any, context?: string) {
winstonLogger.warn(message, { context: context || this.context });
}
debug(message: any, context?: string) {
winstonLogger.debug(message, { context: context || this.context });
}
verbose(message: any, context?: string) {
winstonLogger.verbose(message, { context: context || this.context });
}
}

View File

@@ -0,0 +1,64 @@
import * as winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';
import * as path from 'path';
const logDir = path.join(process.cwd(), 'logs');
// 日志格式
const logFormat = winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.errors({ stack: true }),
winston.format.splat(),
winston.format.printf(({ timestamp, level, message, context, stack }) => {
let log = `${timestamp} [${level}]`;
if (context) {
log += ` [${context}]`;
}
log += ` ${message}`;
if (stack) {
log += `\n${stack}`;
}
return log;
}),
);
// 控制台传输
const consoleTransport = new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
logFormat,
),
});
// 应用日志传输(按天轮转)
const appLogTransport = new DailyRotateFile({
dirname: logDir,
filename: 'application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '30d',
format: logFormat,
});
// 错误日志传输(按天轮转)
const errorLogTransport = new DailyRotateFile({
dirname: logDir,
filename: 'error-%DATE%.log',
datePattern: 'YYYY-MM-DD',
level: 'error',
maxSize: '20m',
maxFiles: '30d',
format: logFormat,
});
// 创建 winston logger 实例
export const winstonLogger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: logFormat,
transports: [
consoleTransport,
appLogTransport,
errorLogTransport,
],
exitOnError: false,
});