Files
webfetch-mcp/monitor-logs.mjs
T

152 lines
4.6 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* WebFetch.MCP - Log Monitor Utility v0.1.7
* Real-time log monitoring for WebFetch.MCP server
*
* This utility monitors the detailed log file generated by the WebFetch.MCP server
* and displays formatted, real-time log entries for debugging and monitoring.
*
* Usage: node monitor-logs.mjs
*
* @author Jay Leon (@manull)
* @license MIT
* @version 0.1.7
* @repository https://github.com/manull/webfetch-mcp
*
* Copyright (c) 2025 Jay Leon (@manull)
* Licensed under the MIT License - see LICENSE file for details
*/
import { watchFile, existsSync, readFileSync, statSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const LOG_FILE = join(__dirname, 'mcp-server-detailed.log');
console.log('🔍 MCP Server Log Monitor');
console.log('========================');
console.log(`Monitoring: ${LOG_FILE}`);
console.log('Press Ctrl+C to stop\n');
// Check if log file exists
if (!existsSync(LOG_FILE)) {
console.log('⏳ Waiting for log file to be created...');
console.log(' (Start your MCP server to begin logging)\n');
}
let lastSize = 0;
// Function to read new content from log file
function readNewContent() {
if (!existsSync(LOG_FILE)) return;
try {
const stats = statSync(LOG_FILE);
const currentSize = stats.size;
if (currentSize > lastSize) {
const content = readFileSync(LOG_FILE, 'utf8');
const newContent = content.slice(lastSize);
// Parse and format the new content
const lines = newContent.split('\n').filter(line => line.trim());
for (const line of lines) {
try {
// Try to parse as JSON log entry
if (line.includes(']: ')) {
const [timestamp, rest] = line.split(']: ', 2);
const category = timestamp.split('] ')[1];
console.log(`\n🔸 ${category} ${timestamp.split('] ')[0]}]`);
try {
const data = JSON.parse(rest);
console.log(formatLogData(category, data));
} catch {
console.log(rest);
}
} else {
console.log(line);
}
} catch (error) {
console.log(line);
}
}
lastSize = currentSize;
}
} catch (error) {
console.error('Error reading log file:', error.message);
}
}
// Format log data for better readability
function formatLogData(category, data) {
switch (category) {
case 'SERVER_STARTUP':
return ` Server: ${data.server_info?.name} v${data.server_info?.version}
SearxNG: ${data.server_info?.searxng_base}
Debug: ${data.server_info?.debug_enabled}
Node: ${data.environment?.node_version}`;
case 'INCOMING_REQUEST':
if (data.method === 'initialize') {
return ` Initialize request from client: ${data.request?.params?.clientInfo?.name}`;
} else if (data.method === 'tools/call') {
return ` Tool call: ${data.tool_name}
Arguments: ${JSON.stringify(data.arguments, null, 4)}`;
} else if (data.method === 'tools/list') {
return ` Tools list requested`;
}
return ` Method: ${data.method}`;
case 'OUTGOING_RESPONSE':
if (data.method === 'tools/call') {
const responseText = data.response?.content?.[0]?.text;
const preview = responseText ? responseText.substring(0, 200) + (responseText.length > 200 ? '...' : '') : 'No text content';
return ` Tool response (${data.tool_name}):
${preview}`;
} else if (data.method === 'tools/list') {
const toolNames = data.response?.tools?.map(t => t.name).join(', ') || 'none';
return ` Available tools: ${toolNames}`;
}
return ` Response for: ${data.method}`;
case 'ERROR':
return ` ❌ Tool: ${data.tool_name}
Error: ${data.error_details?.message}
Args: ${JSON.stringify(data.error_details?.arguments)}`;
case 'SERVER_ERROR':
return ` ❌ ${data.error?.message}`;
case 'SERVER_SHUTDOWN':
return ` Reason: ${data.reason}`;
case 'UNCAUGHT_EXCEPTION':
case 'UNHANDLED_REJECTION':
return ` ❌ ${data.error?.message || data.reason}`;
default:
return ` ${JSON.stringify(data, null, 2)}`;
}
}
// Initial read
readNewContent();
// Watch for file changes
watchFile(LOG_FILE, { interval: 500 }, () => {
readNewContent();
});
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log('\n\n👋 Log monitoring stopped');
process.exit(0);
});