UNPKG

@ai-mapping/mcp-nextjs-dev

Version:

MCP server for managing Next.js development processes with AI tools

173 lines 6.29 kB
import { StateManager } from './state-manager.js'; export class LogCollector { static instance; stateManager; constructor() { this.stateManager = StateManager.getInstance(); } static getInstance() { if (LogCollector.instance === undefined) { LogCollector.instance = new LogCollector(); } return LogCollector.instance; } getFilteredLogs(filter) { const logs = this.stateManager.getLogs(filter); const entries = logs.entries; const summary = entries.reduce((acc, log) => { acc[`${log.level}Count`]++; return acc; }, { errorCount: 0, warnCount: 0, infoCount: 0 }); return { ...logs, summary, }; } getRecentErrors(limit = 10) { const fiveMinutesAgo = Date.now() - 5 * 60 * 1000; return this.stateManager.getLogs({ level: 'error', since: Math.floor(fiveMinutesAgo / 1000), lines: limit, }).entries; } searchLogs(pattern, options = {}) { const { level = 'all', caseSensitive = false, regex = false, limit = 50 } = options; let searchFunction; if (regex) { const flags = caseSensitive ? 'g' : 'gi'; const regexPattern = new RegExp(pattern, flags); searchFunction = (message) => regexPattern.test(message); } else { const searchPattern = caseSensitive ? pattern : pattern.toLowerCase(); searchFunction = (message) => { const searchMessage = caseSensitive ? message : message.toLowerCase(); return searchMessage.includes(searchPattern); }; } const logs = this.stateManager.getLogs({ level: level, lines: 1000, }).entries; const matchingLogs = logs.filter((log) => searchFunction(log.message)); return matchingLogs.slice(-limit); } getCompilationStatus() { const recentLogs = this.stateManager.getLogs({ lines: 100, }).entries; let isCompiling = false; let hasErrors = false; let hasWarnings = false; let lastCompilationTime; let errorCount = 0; let warningCount = 0; for (const log of recentLogs.reverse()) { const message = log.message.toLowerCase(); if (message.includes('compiling') || message.includes('building')) { isCompiling = true; lastCompilationTime = new Date(log.timestamp); } if (message.includes('compiled successfully') || message.includes('ready in')) { isCompiling = false; lastCompilationTime = new Date(log.timestamp); break; } if (message.includes('failed to compile') || message.includes('compilation error')) { isCompiling = false; hasErrors = true; lastCompilationTime = new Date(log.timestamp); break; } if (log.level === 'error') { errorCount++; hasErrors = true; } if (log.level === 'warn') { warningCount++; hasWarnings = true; } } const result = { isCompiling, hasErrors, hasWarnings, errorCount, warningCount, }; if (lastCompilationTime) { result.lastCompilationTime = lastCompilationTime; } return result; } getStartupLogs() { return this.searchLogs('ready|started|listening|server', { caseSensitive: false, regex: true, limit: 20, }); } getLogsByTimeRange(startTime, endTime) { const allLogs = this.stateManager.getLogs({ lines: 1000 }).entries; return allLogs.filter((log) => { const logTime = new Date(log.timestamp); return logTime >= startTime && logTime <= endTime; }); } exportLogs(filter) { const logs = filter ? this.getFilteredLogs(filter) : this.stateManager.getLogs({}); const exportData = { exportTime: new Date().toISOString(), serverInfo: this.stateManager.getStatus(), totalLogs: logs.total, logs: logs.entries, }; return JSON.stringify(exportData, null, 2); } clearOldLogs(keepRecentMinutes = 60) { const cutoffTime = Date.now() - keepRecentMinutes * 60 * 1000; return this.stateManager.clearOldLogs(cutoffTime); } getLogStatistics() { const allLogs = this.stateManager.getLogs({ lines: 1000 }).entries; if (allLogs.length === 0) { return { totalLogs: 0, logsByLevel: { error: 0, warn: 0, info: 0 }, logsBySource: {}, averageLogsPerMinute: 0, }; } const logsByLevel = { error: 0, warn: 0, info: 0 }; const logsBySource = {}; const firstLog = allLogs[0]; if (!firstLog) { throw new Error('No logs available for statistics'); } let oldestTime = new Date(firstLog.timestamp); let newestTime = new Date(firstLog.timestamp); for (const log of allLogs) { logsByLevel[log.level]++; logsBySource[log.source] = (logsBySource[log.source] ?? 0) + 1; const logTime = new Date(log.timestamp); if (logTime < oldestTime) { oldestTime = logTime; } if (logTime > newestTime) { newestTime = logTime; } } const timeRangeMinutes = (newestTime.getTime() - oldestTime.getTime()) / (1000 * 60); const averageLogsPerMinute = timeRangeMinutes > 0 ? allLogs.length / timeRangeMinutes : 0; return { totalLogs: allLogs.length, logsByLevel, logsBySource, oldestLog: oldestTime, newestLog: newestTime, averageLogsPerMinute: Math.round(averageLogsPerMinute * 100) / 100, }; } } //# sourceMappingURL=log-collector.js.map