UNPKG

sap-b1-mcp-server

Version:

SAP Business One Service Layer MCP Server

233 lines 6.85 kB
export var LogLevel; (function (LogLevel) { LogLevel[LogLevel["ERROR"] = 0] = "ERROR"; LogLevel[LogLevel["WARN"] = 1] = "WARN"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG"; })(LogLevel || (LogLevel = {})); export class Logger { level; context; constructor(level = LogLevel.INFO, context = {}) { this.level = level; this.context = context; } /** * Create a child logger with additional context */ child(context) { return new Logger(this.level, { ...this.context, ...context }); } /** * Log an error message */ error(message, error, context) { if (this.level >= LogLevel.ERROR) { this.log({ timestamp: new Date().toISOString(), level: LogLevel.ERROR, message, context: { ...this.context, ...context }, error }); } } /** * Log a warning message */ warn(message, context) { if (this.level >= LogLevel.WARN) { this.log({ timestamp: new Date().toISOString(), level: LogLevel.WARN, message, context: { ...this.context, ...context } }); } } /** * Log an info message */ info(message, context) { if (this.level >= LogLevel.INFO) { this.log({ timestamp: new Date().toISOString(), level: LogLevel.INFO, message, context: { ...this.context, ...context } }); } } /** * Log a debug message */ debug(message, context) { if (this.level >= LogLevel.DEBUG) { this.log({ timestamp: new Date().toISOString(), level: LogLevel.DEBUG, message, context: { ...this.context, ...context } }); } } /** * Log SAP API request */ logSAPRequest(method, endpoint, params) { this.debug('SAP API Request', { method, endpoint, params: params ? JSON.stringify(params) : undefined }); } /** * Log SAP API response */ logSAPResponse(method, endpoint, status, responseTime) { this.debug('SAP API Response', { method, endpoint, status, responseTime: responseTime ? `${responseTime}ms` : undefined }); } /** * Log SAP API error */ logSAPError(method, endpoint, error, responseTime) { this.error('SAP API Error', error, { method, endpoint, responseTime: responseTime ? `${responseTime}ms` : undefined }); } /** * Log MCP tool execution */ logToolExecution(toolName, args, success, duration) { this.info('MCP Tool Execution', { tool: toolName, success, duration: duration ? `${duration}ms` : undefined, args: JSON.stringify(args, null, 2).substring(0, 500) // Truncate large arguments }); } /** * Log session events */ logSessionEvent(event, sessionId) { this.info('Session Event', { event, sessionId: sessionId ? `***${sessionId.slice(-8)}` : undefined // Mask session ID for security }); } /** * Set log level */ setLevel(level) { this.level = level; } /** * Get current log level */ getLevel() { return this.level; } /** * Internal log method */ log(entry) { const levelString = LogLevel[entry.level]; const contextString = entry.context && Object.keys(entry.context).length > 0 ? ` ${JSON.stringify(entry.context)}` : ''; const errorString = entry.error ? ` | Error: ${entry.error.message}${entry.error.stack ? `\n${entry.error.stack}` : ''}` : ''; // Log to stderr so it doesn't interfere with STDIO transport console.error(`[${entry.timestamp}] ${levelString}: ${entry.message}${contextString}${errorString}`); } /** * Create logger from environment */ static fromEnvironment() { const logLevelEnv = process.env.LOG_LEVEL?.toUpperCase(); let level = LogLevel.INFO; switch (logLevelEnv) { case 'ERROR': level = LogLevel.ERROR; break; case 'WARN': level = LogLevel.WARN; break; case 'INFO': level = LogLevel.INFO; break; case 'DEBUG': level = LogLevel.DEBUG; break; } const context = { service: 'SAP B1 MCP Server', version: process.env.npm_package_version || '1.0.0', nodeVersion: process.version, pid: process.pid }; return new Logger(level, context); } /** * Format error for logging */ static formatError(error) { if (error instanceof Error) { return { message: error.message, stack: error.stack, code: error.code }; } return { message: String(error) }; } /** * Sanitize sensitive data for logging */ static sanitize(data) { if (typeof data !== 'object' || data === null) { return data; } const sanitized = Array.isArray(data) ? [...data] : { ...data }; // List of sensitive field names to mask const sensitiveFields = [ 'password', 'token', 'secret', 'key', 'auth', 'authorization', 'sessionid', 'session_id', 'cookie', 'passwd', 'pwd' ]; const sanitizeValue = (obj) => { if (typeof obj !== 'object' || obj === null) { return obj; } if (Array.isArray(obj)) { return obj.map(sanitizeValue); } const result = {}; for (const [key, value] of Object.entries(obj)) { if (sensitiveFields.some(field => key.toLowerCase().includes(field))) { result[key] = '***masked***'; } else if (typeof value === 'object') { result[key] = sanitizeValue(value); } else { result[key] = value; } } return result; }; return sanitizeValue(sanitized); } } // Export default logger instance export const logger = Logger.fromEnvironment(); //# sourceMappingURL=logger.js.map