Files
plates-server/src/common/logger/winston.config.ts
2025-08-13 15:17:33 +08:00

136 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);