mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-05-19 04:49:36 +08:00
181 lines
4.0 KiB
TypeScript
181 lines
4.0 KiB
TypeScript
/**
|
|
* 导入日志模块
|
|
* 实时记录导入过程的性能指标、错误和警告信息
|
|
*/
|
|
|
|
import * as fs from 'fs'
|
|
import * as path from 'path'
|
|
import { getDbDir } from './dbCore'
|
|
|
|
// 日志级别
|
|
export enum LogLevel {
|
|
ERROR = 'ERROR',
|
|
INFO = 'INFO',
|
|
}
|
|
|
|
// 状态
|
|
let lastLogTime = Date.now()
|
|
let lastMessageCount = 0
|
|
let currentLogFile: string | null = null
|
|
|
|
// 统计计数器
|
|
let errorCount = 0
|
|
|
|
/**
|
|
* 获取性能日志目录
|
|
*/
|
|
function getLogDir(): string {
|
|
const dbDir = getDbDir()
|
|
const logDir = path.join(path.dirname(dbDir), 'logs', 'import')
|
|
if (!fs.existsSync(logDir)) {
|
|
fs.mkdirSync(logDir, { recursive: true })
|
|
}
|
|
return logDir
|
|
}
|
|
|
|
/**
|
|
* 初始化日志文件(实时写入)
|
|
*/
|
|
export function initPerfLog(sessionId: string): void {
|
|
try {
|
|
const logDir = getLogDir()
|
|
currentLogFile = path.join(logDir, `import_${sessionId}_${Date.now()}.log`)
|
|
// 写入头部
|
|
fs.writeFileSync(currentLogFile, `=== 导入日志 ===\n开始时间: ${new Date().toISOString()}\n\n`, 'utf-8')
|
|
} catch {
|
|
// 忽略初始化失败
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 实时记录性能日志(每次追加写入文件)
|
|
*/
|
|
export function logPerf(event: string, messagesProcessed: number, batchSize?: number): void {
|
|
const now = Date.now()
|
|
const duration = now - lastLogTime
|
|
const messagesDelta = messagesProcessed - lastMessageCount
|
|
const speed = duration > 0 ? Math.round((messagesDelta / duration) * 1000) : 0
|
|
|
|
// 获取内存使用
|
|
let memory = 0
|
|
try {
|
|
const used = process.memoryUsage()
|
|
memory = Math.round(used.heapUsed / 1024 / 1024)
|
|
} catch {
|
|
// 忽略
|
|
}
|
|
|
|
const logLine =
|
|
`[${new Date().toISOString()}] ${event} | ` +
|
|
`消息: ${messagesProcessed.toLocaleString()} | ` +
|
|
`耗时: ${duration}ms | ` +
|
|
`速度: ${speed.toLocaleString()}/秒 | ` +
|
|
`内存: ${memory}MB` +
|
|
(batchSize ? ` | 批次: ${batchSize}` : '') +
|
|
'\n'
|
|
|
|
// 实时写入文件
|
|
if (currentLogFile) {
|
|
try {
|
|
fs.appendFileSync(currentLogFile, logLine, 'utf-8')
|
|
} catch {
|
|
// 忽略写入失败
|
|
}
|
|
}
|
|
|
|
lastLogTime = now
|
|
lastMessageCount = messagesProcessed
|
|
}
|
|
|
|
/**
|
|
* 追加详细日志(分阶段耗时)
|
|
*/
|
|
export function logPerfDetail(detail: string): void {
|
|
if (currentLogFile) {
|
|
try {
|
|
fs.appendFileSync(currentLogFile, ` ${detail}\n`, 'utf-8')
|
|
} catch {
|
|
// 忽略
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 重置性能日志状态
|
|
*/
|
|
export function resetPerfLog(): void {
|
|
lastLogTime = Date.now()
|
|
lastMessageCount = 0
|
|
currentLogFile = null
|
|
errorCount = 0
|
|
}
|
|
|
|
/**
|
|
* 获取当前日志文件路径
|
|
*/
|
|
export function getCurrentLogFile(): string | null {
|
|
return currentLogFile
|
|
}
|
|
|
|
// ==================== 通用日志函数 ====================
|
|
|
|
/**
|
|
* 写入日志行
|
|
*/
|
|
function writeLogLine(level: LogLevel, message: string): void {
|
|
if (!currentLogFile) return
|
|
|
|
const logLine = `[${new Date().toISOString()}] [${level}] ${message}\n`
|
|
try {
|
|
fs.appendFileSync(currentLogFile, logLine, 'utf-8')
|
|
} catch {
|
|
// 忽略写入失败
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 记录错误日志
|
|
* @param message 错误描述
|
|
* @param error 可选的 Error 对象
|
|
*/
|
|
export function logError(message: string, error?: Error): void {
|
|
errorCount++
|
|
const errorDetail = error ? `: ${error.message}` : ''
|
|
writeLogLine(LogLevel.ERROR, `${message}${errorDetail}`)
|
|
}
|
|
|
|
/**
|
|
* 记录信息日志
|
|
* @param message 信息描述
|
|
*/
|
|
export function logInfo(message: string): void {
|
|
writeLogLine(LogLevel.INFO, message)
|
|
}
|
|
|
|
/**
|
|
* 获取错误计数
|
|
*/
|
|
export function getErrorCount(): number {
|
|
return errorCount
|
|
}
|
|
|
|
/**
|
|
* 写入日志摘要(导入完成时调用)
|
|
*/
|
|
export function logSummary(totalMessages: number, totalMembers: number): void {
|
|
if (!currentLogFile) return
|
|
|
|
const summary = `
|
|
=== 导入摘要 ===
|
|
结束时间: ${new Date().toISOString()}
|
|
总消息数: ${totalMessages.toLocaleString()}
|
|
总成员数: ${totalMembers.toLocaleString()}
|
|
错误数: ${errorCount}
|
|
`
|
|
try {
|
|
fs.appendFileSync(currentLogFile, summary, 'utf-8')
|
|
} catch {
|
|
// 忽略
|
|
}
|
|
}
|