Skip to main content
Glama

Game Asset Generator

logger.js3.56 kB
import { promises as fs } from "fs"; import path from "path"; export async function log(level = "INFO", message, workDir) { const timestamp = new Date().toISOString(); const logMessage = `[${level.toUpperCase()}] ${timestamp} - ${message}\n`; console.error(logMessage.trim()); try { const logDir = path.join(workDir, "logs"); await fs.mkdir(logDir, { recursive: true }); const logFile = path.join(logDir, "server.log"); await fs.appendFile(logFile, logMessage); } catch (err) { console.error(`Failed to write to log file: ${err}`); } } export async function logOperation(toolName, operationId, status, details = {}, workDir) { const level = status === "ERROR" ? "ERROR" : "INFO"; const detailsStr = Object.entries(details) .map(([key, value]) => `${key}: ${value}`) .join(", "); const logMessage = `Operation ${operationId} [${toolName}] - ${status}${detailsStr ? " - " + detailsStr : ""}`; await log(level, logMessage, workDir); if (!global.operationUpdates[operationId]) { global.operationUpdates[operationId] = []; } global.operationUpdates[operationId].push({ status, details, timestamp: new Date().toISOString(), message: logMessage, }); if (global.operationUpdates[operationId].length > 100) { global.operationUpdates[operationId].shift(); } } /** * Enhanced error logging function that captures detailed information about errors * @param {Error} error - The error object * @param {string} operationId - The ID of the operation that failed * @param {string} workDir - The working directory for log files * @param {Object} contextInfo - Additional context information about the operation */ export async function logDetailedError(error, operationId, workDir, contextInfo = {}) { // Log the basic error message await log('ERROR', `Error in operation ${operationId}: ${error.message}`, workDir); // Log the stack trace if available if (error.stack) { await log('ERROR', `Stack trace for operation ${operationId}:\n${error.stack}`, workDir); } // Log API response data if available if (error.response) { await log('ERROR', `API response status for operation ${operationId}: ${error.response.status}`, workDir); try { const responseData = typeof error.response.data === 'object' ? JSON.stringify(error.response.data, null, 2) : error.response.data; await log('ERROR', `API response data for operation ${operationId}:\n${responseData}`, workDir); } catch (jsonError) { await log('ERROR', `API response data (non-JSON) for operation ${operationId}: ${error.response.data}`, workDir); } } // Log any additional context information if (Object.keys(contextInfo).length > 0) { const contextStr = Object.entries(contextInfo) .map(([key, value]) => { // Handle objects by converting them to JSON strings if (typeof value === 'object' && value !== null) { try { return `${key}: ${JSON.stringify(value)}`; } catch (e) { return `${key}: [Complex Object]`; } } return `${key}: ${value}`; }) .join('\n'); await log('ERROR', `Context information for operation ${operationId}:\n${contextStr}`, workDir); } // Log to operation updates await logOperation('ERROR', operationId, 'ERROR', { error: error.message, stack: error.stack ? 'See logs for details' : 'Not available', context: 'See logs for details', timestamp: new Date().toISOString() }, workDir); }

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/MubarakHAlketbi/game-asset-mcp'

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