UNPKG

@baguskto/saham

Version:

MCP Server untuk data saham Indonesia (IDX) - Implementasi Node.js/TypeScript

132 lines 4.92 kB
"use strict"; /** * Logging utilities for IDX MCP Server */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.logger = void 0; const winston_1 = __importDefault(require("winston")); const config_1 = require("../config"); // Safe JSON stringify that handles circular references and errors function safeStringify(obj) { try { return JSON.stringify(obj, (_key, value) => { // Handle errors by converting them to simple objects if (value instanceof Error) { return { name: value.name, message: value.message, stack: value.stack }; } // Handle circular references if (typeof value === 'object' && value !== null) { if (value.constructor?.name === 'ClientRequest' || value.constructor?.name === 'IncomingMessage' || value.constructor?.name === 'Socket') { return '[Circular Reference]'; } } return value; }); } catch (error) { return `[Failed to stringify: ${error instanceof Error ? error.message : String(error)}]`; } } class Logger { static instance; logger; constructor() { this.logger = this.createLogger(); } static getInstance() { if (!Logger.instance) { Logger.instance = new Logger(); } return Logger.instance; } createLogger() { const logConfig = config_1.config.getLogging(); const transports = []; // Check if in MCP mode const isMcpMode = process.env['IDX_MCP_LOG_LEVEL'] === 'error' || process.argv.includes('--mcp'); if (!isMcpMode) { transports.push(new winston_1.default.transports.Console({ format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.timestamp(), winston_1.default.format.printf(({ timestamp, level, message, ...meta }) => { let log = `${timestamp} [${level}]: ${message}`; if (Object.keys(meta).length > 0) { log += ` ${safeStringify(meta)}`; } return log; })) })); } else { // In MCP mode, completely suppress console logging to avoid stdout pollution // Only enable if log level is error and only to stderr const logLevel = process.env['IDX_MCP_LOG_LEVEL'] || logConfig.level; if (logLevel === 'error') { transports.push(new winston_1.default.transports.Console({ stderrLevels: ['error'], format: winston_1.default.format.combine(winston_1.default.format.printf(({ level, message, ...meta }) => { let log = `[idx-mcp-server] [${level}] ${message}`; if (Object.keys(meta).length > 0) { log += ` ${safeStringify(meta)}`; } return log; })) })); } } if (logConfig.file) { transports.push(new winston_1.default.transports.File({ filename: logConfig.file, format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.json()), maxsize: 10 * 1024 * 1024, // 10MB maxFiles: 5 })); } // Use environment log level if in MCP mode, otherwise use config const logLevel = process.env['IDX_MCP_LOG_LEVEL'] || logConfig.level; return winston_1.default.createLogger({ level: logLevel, transports, exitOnError: false }); } error(message, meta) { this.logger.error(message, meta); } warn(message, meta) { this.logger.warn(message, meta); } info(message, meta) { this.logger.info(message, meta); } debug(message, meta) { this.logger.debug(message, meta); } logMcpRequest(functionName, params, responseTime, error) { const logData = { functionName, params, responseTime, success: !error, error }; if (error) { this.error(`MCP Request Failed: ${functionName}`, logData); } else { this.info(`MCP Request: ${functionName}`, logData); } } logPerformanceMetrics(metrics) { this.info('Performance Metrics', metrics); } } exports.logger = Logger.getInstance(); //# sourceMappingURL=logger.js.map