Skip to main content
Glama
wqhui
by wqhui
logger.ts3.47 kB
import { promises as fs } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; /** * 增强的日志工具类,支持控制台和文件输出 */ export class Logger { private logLevel: string; private logFilePath: string; private enableFileLogging: boolean; constructor() { this.logLevel = process.env.LOG_LEVEL || 'info'; this.enableFileLogging = process.env.ENABLE_FILE_LOGGING !== 'false'; // 设置日志文件路径,默认在项目根目录的 logs 文件夹 const projectRoot = process.cwd(); const logDir = join(projectRoot, 'logs'); const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD 格式 this.logFilePath = join(logDir, `gitlab-mcp-${today}.log`); // 确保日志目录存在 this.ensureLogDirectory(); } private async ensureLogDirectory(): Promise<void> { try { const logDir = dirname(this.logFilePath); await fs.mkdir(logDir, { recursive: true }); } catch (error) { console.error('Failed to create log directory:', error); this.enableFileLogging = false; } } private shouldLog(level: string): boolean { const levels = ['error', 'warn', 'info', 'debug']; const currentLevelIndex = levels.indexOf(this.logLevel); const messageLevelIndex = levels.indexOf(level); return messageLevelIndex <= currentLevelIndex; } private formatMessage(level: string, message: string, ...args: any[]): string { const timestamp = new Date().toISOString(); const formattedArgs = args.length > 0 ? ' ' + args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg) ).join(' ') : ''; return `[${timestamp}] [${level.toUpperCase()}] ${message}${formattedArgs}`; } private async writeToFile(formattedMessage: string): Promise<void> { if (!this.enableFileLogging) return; try { await fs.appendFile(this.logFilePath, formattedMessage + '\n', 'utf8'); } catch (error) { // 如果文件写入失败,只在控制台显示错误,避免递归调用 console.error('Failed to write to log file:', error); } } private async log(level: string, message: string, ...args: any[]): Promise<void> { if (!this.shouldLog(level)) return; const formattedMessage = this.formatMessage(level, message, ...args); // 输出到控制台 switch (level) { case 'error': console.error(formattedMessage); break; case 'warn': console.warn(formattedMessage); break; default: console.log(formattedMessage); break; } // 异步写入文件,不阻塞主流程 this.writeToFile(formattedMessage).catch(() => { // 静默处理文件写入错误 }); } error(message: string, ...args: any[]): void { this.log('error', message, ...args); } warn(message: string, ...args: any[]): void { this.log('warn', message, ...args); } info(message: string, ...args: any[]): void { this.log('info', message, ...args); } debug(message: string, ...args: any[]): void { this.log('debug', message, ...args); } /** * 获取当前日志文件路径 */ getLogFilePath(): string { return this.logFilePath; } /** * 检查文件日志是否启用 */ isFileLoggingEnabled(): boolean { return this.enableFileLogging; } } // 导出单例实例 export const logger = new Logger();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wqhui/mcp-gitlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server