feat: 初始化项目

This commit is contained in:
richarjiang
2025-08-13 15:17:33 +08:00
commit 4f9d648a50
72 changed files with 29051 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
import * as winston from 'winston';
import * as DailyRotateFile from 'winston-daily-rotate-file';
import { WinstonModule } from 'nest-winston';
import * as path from 'path';
// 日志目录
const LOG_DIR = 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.printf((info) => {
const { timestamp, level, message, context, stack, ...meta } = info;
const contextStr = context ? `[${context}] ` : '';
const stackStr = stack ? `\n${stack}` : '';
// 如果有额外的元数据将其格式化为JSON字符串
const metaStr = Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta, null, 2)}` : '';
return `${timestamp} [${level.toUpperCase()}] ${contextStr}${message}${metaStr}${stackStr}`;
}),
);
// 控制台格式(带颜色)
const consoleFormat = winston.format.combine(
winston.format.colorize(),
winston.format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
winston.format.printf((info) => {
const { timestamp, level, message, context, stack, ...meta } = info;
const contextStr = context ? `[${context}] ` : '';
const stackStr = stack ? `\n${stack}` : '';
// 如果有额外的元数据将其格式化为JSON字符串
const metaStr = Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta, null, 2)}` : '';
return `${timestamp} ${level} ${contextStr}${message}${metaStr}${stackStr}`;
}),
);
// 创建日志传输器
const createTransports = () => {
const transports: winston.transport[] = [];
// 控制台输出
transports.push(
new winston.transports.Console({
format: consoleFormat,
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
}),
);
// 错误日志文件按日期滚动保留7天
transports.push(
new DailyRotateFile({
filename: path.join(LOG_DIR, 'error-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
level: 'error',
format: logFormat,
maxFiles: '7d', // 保留7天
maxSize: '20m', // 单个文件最大20MB
auditFile: path.join(LOG_DIR, '.audit-error.json'),
}),
);
// 应用日志文件按日期滚动保留7天
transports.push(
new DailyRotateFile({
filename: path.join(LOG_DIR, 'app-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
level: 'info',
format: logFormat,
maxFiles: '7d', // 保留7天
maxSize: '20m', // 单个文件最大20MB
auditFile: path.join(LOG_DIR, '.audit-app.json'),
}),
);
// 调试日志文件(仅在开发环境)
if (process.env.NODE_ENV !== 'production') {
transports.push(
new DailyRotateFile({
filename: path.join(LOG_DIR, 'debug-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
level: 'debug',
format: logFormat,
maxFiles: '7d', // 保留7天
maxSize: '20m', // 单个文件最大20MB
auditFile: path.join(LOG_DIR, '.audit-debug.json'),
}),
);
}
return transports;
};
// Winston配置
export const winstonConfig = {
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
format: logFormat,
transports: createTransports(),
// 处理未捕获的异常
exceptionHandlers: [
new DailyRotateFile({
filename: path.join(LOG_DIR, 'exceptions-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
format: logFormat,
maxFiles: '7d',
maxSize: '20m',
auditFile: path.join(LOG_DIR, '.audit-exceptions.json'),
}),
],
// 处理未处理的Promise拒绝
rejectionHandlers: [
new DailyRotateFile({
filename: path.join(LOG_DIR, 'rejections-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
format: logFormat,
maxFiles: '7d',
maxSize: '20m',
auditFile: path.join(LOG_DIR, '.audit-rejections.json'),
}),
],
};
// 创建Winston Logger实例
export const createWinstonLogger = () => {
return WinstonModule.createLogger(winstonConfig);
};
// 导出winston实例供直接使用
export const logger = winston.createLogger(winstonConfig);