feat:添加日志功能

This commit is contained in:
jianuo
2025-12-19 20:01:45 +08:00
parent 8166c95af4
commit a4a3a60db7
11 changed files with 429 additions and 5 deletions

View File

@@ -61,6 +61,15 @@ export class LogManagementService {
this.maxSize = this.configService.get('LOG_MAX_SIZE', '10m');
}
/**
* 获取日志目录的绝对路径
*
* 说明:用于后台打包下载 logs/ 整目录。
*/
getLogDirAbsolutePath(): string {
return path.resolve(this.logDir);
}
/**
* 定期清理过期日志文件
*
@@ -307,6 +316,67 @@ export class LogManagementService {
}
}
/**
* 获取运行日志尾部(用于后台查看)
*
* 说明:
* - 开发环境默认读取 dev.log
* - 生产环境默认读取 app.log可选 access/error
* - 通过读取文件尾部一定字节数实现“近似 tail”避免大文件全量读取
*/
async getRuntimeLogTail(options?: {
type?: 'app' | 'access' | 'error' | 'dev';
lines?: number;
}): Promise<{
file: string;
updated_at: string;
lines: string[];
}> {
const isProduction = this.configService.get('NODE_ENV') === 'production';
const requestedLines = Math.max(1, Math.min(Number(options?.lines ?? 200), 2000));
const requestedType = options?.type;
const allowedFiles = isProduction
? {
app: 'app.log',
access: 'access.log',
error: 'error.log',
}
: {
dev: 'dev.log',
};
const defaultType = isProduction ? 'app' : 'dev';
const typeKey = (requestedType && requestedType in allowedFiles ? requestedType : defaultType) as keyof typeof allowedFiles;
const fileName = allowedFiles[typeKey];
const filePath = path.join(this.logDir, fileName);
if (!fs.existsSync(filePath)) {
return { file: fileName, updated_at: new Date().toISOString(), lines: [] };
}
const stats = fs.statSync(filePath);
const maxBytes = 256 * 1024; // 256KB 足够覆盖常见的数百行日志
const readBytes = Math.min(stats.size, maxBytes);
const startPos = Math.max(0, stats.size - readBytes);
const fd = fs.openSync(filePath, 'r');
try {
const buffer = Buffer.alloc(readBytes);
fs.readSync(fd, buffer, 0, readBytes, startPos);
const text = buffer.toString('utf8');
const allLines = text.split(/\r?\n/).filter((l) => l.length > 0);
const tailLines = allLines.slice(-requestedLines);
return {
file: fileName,
updated_at: stats.mtime.toISOString(),
lines: tailLines,
};
} finally {
fs.closeSync(fd);
}
}
/**
* 解析最大文件数配置
*