/** * LogManager - 统一日志管理器 * * 提供全局日志管理功能: * - 多会话管理 * - 多后端支持 * - 全局配置 * - 日志查询 */ const path = require('path'); const { EventEmitter } = require('events'); const { LogSession } = require('./LogSession'); const { CompositeBackend } = require('./backends/CompositeBackend'); const { FileBackend } = require('./backends/FileBackend'); const { ConsoleBackend } = require('./backends/ConsoleBackend'); // 获取项目根目录 (从 server/src/core/logging/LogManager.js 向上回溯) const PROJECT_ROOT = path.resolve(__dirname, '../../../../'); class LogManager extends EventEmitter { constructor(options = {}) { super(); this.options = { // 默认使用项目根目录的 .logs/ baseDir: options.baseDir || path.join(PROJECT_ROOT, '.logs'), enableConsole: options.enableConsole !== false, enableFile: options.enableFile !== false, ...options, }; this.sessions = new Map(); // sessionId -> LogSession this.backend = new CompositeBackend(); this.initialized = false; this.globalMetadata = {}; } /** * 初始化日志管理器 */ async init() { if (this.initialized) return; // 添加文件后端 if (this.options.enableFile) { const fileBackend = new FileBackend({ baseDir: this.options.baseDir, maxFileSize: this.options.maxFileSize, maxFiles: this.options.maxFiles, }); this.backend.add(fileBackend); } // 添加控制台后端 if (this.options.enableConsole) { const consoleBackend = new ConsoleBackend({ colorize: this.options.colorize !== false, pretty: this.options.pretty !== false, level: this.options.consoleLevel || 'info', }); this.backend.add(consoleBackend); } await this.backend.init(); this.initialized = true; this.emit('initialized'); } /** * 创建新会话 * @param {string} sessionId - 会话ID * @param {Object} options - 会话选项 * @returns {LogSession} */ createSession(sessionId, options = {}) { if (!this.initialized) { throw new Error('LogManager not initialized. Call init() first.'); } if (this.sessions.has(sessionId)) { console.warn(`[LogManager] Session ${sessionId} already exists, returning existing session`); return this.sessions.get(sessionId); } const session = new LogSession(sessionId, this.backend, { metadata: { ...this.globalMetadata, ...options.metadata, }, ...options, }); // 转发事件 session.on('log', (entry) => { this.emit('log', entry); }); this.sessions.set(sessionId, session); this.emit('session_created', { sessionId, session }); // 记录会话开始 session.logEvent(null, 'session_start', { workDir: options.workDir, requirement: options.requirement, config: options.config, }); return session; } /** * 获取会话 * @param {string} sessionId - 会话ID * @returns {LogSession|null} */ getSession(sessionId) { return this.sessions.get(sessionId) || null; } /** * 获取或创建会话 * @param {string} sessionId - 会话ID * @param {Object} options - 创建选项(如果会话不存在) * @returns {LogSession} */ getOrCreateSession(sessionId, options = {}) { return this.getSession(sessionId) || this.createSession(sessionId, options); } /** * 关闭会话 * @param {string} sessionId - 会话ID */ async closeSession(sessionId) { const session = this.sessions.get(sessionId); if (!session) return; // 记录会话结束 await session.logEvent(null, 'session_end', {}); await session.close(); this.sessions.delete(sessionId); this.emit('session_closed', { sessionId }); } /** * 关闭所有会话 */ async closeAllSessions() { const promises = []; for (const sessionId of this.sessions.keys()) { promises.push(this.closeSession(sessionId)); } await Promise.all(promises); } /** * 注册自定义后端 * @param {string} name - 后端名称 * @param {BaseBackend} backend - 后端实例 */ registerBackend(name, backend) { backend.name = name; this.backend.add(backend); } /** * 设置全局元数据 * @param {Object} metadata - 元数据对象 */ setGlobalMetadata(metadata) { this.globalMetadata = { ...this.globalMetadata, ...metadata }; } /** * 查询日志 * @param {Object} filters - 查询条件 */ async query(filters = {}) { if (!this.initialized) { throw new Error('LogManager not initialized'); } return this.backend.query(filters); } /** * 获取所有会话列表 */ getSessions() { return Array.from(this.sessions.keys()); } /** * 生成会话报告 * @param {string} sessionId - 会话ID */ async generateReport(sessionId) { const session = this.sessions.get(sessionId); if (session) { return session.generateReport(); } // 如果会话已关闭,从后端查询 const entries = await this.backend.query({ sessionId, limit: 10000 }); return { sessionId, entryCount: entries.length, archived: true, entries: entries.slice(0, 100), // 返回最近100条 }; } /** * 关闭日志管理器 */ async close() { await this.closeAllSessions(); await this.backend.close(); this.initialized = false; this.emit('closed'); } // ============ 快捷方法 ============ /** * 记录系统级事件(不关联特定会话) */ async logSystemEvent(eventType, payload, level = 'info') { if (!this.initialized) return; const entry = { timestamp: new Date().toISOString(), sequence: 0, level, category: 'system', eventType, payload, metadata: this.globalMetadata, }; await this.backend.write(entry); this.emit('log', entry); } } // 全局实例 let globalInstance = null; let initPromise = null; /** * 获取全局 LogManager 实例(自动初始化) */ function getGlobalLogManager(options = {}) { if (!globalInstance) { globalInstance = new LogManager({ enableConsole: false, // 全局实例默认不输出控制台 enableFile: true, ...options, }); // 异步初始化,不阻塞返回 initPromise = globalInstance.init().catch(err => { console.error('[LogManager] Auto-init failed:', err); }); } return globalInstance; } /** * 等待全局 LogManager 初始化完成 */ async function waitForGlobalLogManager() { getGlobalLogManager(); if (initPromise) await initPromise; return globalInstance; } /** * 设置全局 LogManager 实例 */ function setGlobalLogManager(instance) { globalInstance = instance; } module.exports = { LogManager, getGlobalLogManager, setGlobalLogManager, waitForGlobalLogManager, };