@ai-mapping/mcp-nextjs-dev
Version:
MCP server for managing Next.js development processes with AI tools
173 lines • 6.29 kB
JavaScript
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