Skip to main content
Glama

Bybit MCP Server

by sammcj
logService.ts5.51 kB
/** * Log Service - Captures and streams application logs for debugging */ export interface LogEntry { id: string; timestamp: number; level: 'log' | 'info' | 'warn' | 'error' | 'debug'; message: string; data?: any; source?: string; } export class LogService { private logs: LogEntry[] = []; private listeners: Set<(logs: LogEntry[]) => void> = new Set(); private maxLogs = 1000; // Keep last 1000 logs private originalConsole: { log: typeof console.log; info: typeof console.info; warn: typeof console.warn; error: typeof console.error; debug: typeof console.debug; }; constructor() { // Store original console methods this.originalConsole = { log: console.log.bind(console), info: console.info.bind(console), warn: console.warn.bind(console), error: console.error.bind(console), debug: console.debug.bind(console), }; // Intercept console methods this.interceptConsole(); } private interceptConsole(): void { const self = this; console.log = function(...args: any[]) { self.addLog('log', self.formatMessage(args), args.length > 1 ? args.slice(1) : undefined); self.originalConsole.log(...args); }; console.info = function(...args: any[]) { self.addLog('info', self.formatMessage(args), args.length > 1 ? args.slice(1) : undefined); self.originalConsole.info(...args); }; console.warn = function(...args: any[]) { self.addLog('warn', self.formatMessage(args), args.length > 1 ? args.slice(1) : undefined); self.originalConsole.warn(...args); }; console.error = function(...args: any[]) { self.addLog('error', self.formatMessage(args), args.length > 1 ? args.slice(1) : undefined); self.originalConsole.error(...args); }; console.debug = function(...args: any[]) { self.addLog('debug', self.formatMessage(args), args.length > 1 ? args.slice(1) : undefined); self.originalConsole.debug(...args); }; } private formatMessage(args: any[]): string { return args.map(arg => { if (typeof arg === 'string') { return arg; } else if (typeof arg === 'object') { try { return JSON.stringify(arg, null, 2); } catch { return String(arg); } } else { return String(arg); } }).join(' '); } private addLog(level: LogEntry['level'], message: string, data?: any): void { const entry: LogEntry = { id: `log_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, timestamp: Date.now(), level, message, data, source: this.getSource() }; this.logs.push(entry); // Keep only the last maxLogs entries if (this.logs.length > this.maxLogs) { this.logs = this.logs.slice(-this.maxLogs); } // Notify listeners this.notifyListeners(); } private getSource(): string { try { const stack = new Error().stack; if (stack) { const lines = stack.split('\n'); // Find the first line that's not from this service for (let i = 3; i < lines.length; i++) { const line = lines[i]; if (line && !line.includes('logService.ts') && !line.includes('console.')) { const match = line.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/); if (match) { const [, , file, lineNum] = match; const fileName = file.split('/').pop() || file; return `${fileName}:${lineNum}`; } } } } } catch { // Ignore errors in source detection } return 'unknown'; } /** * Get all logs */ getLogs(): LogEntry[] { return [...this.logs]; } /** * Get logs filtered by level */ getLogsByLevel(levels: LogEntry['level'][]): LogEntry[] { return this.logs.filter(log => levels.includes(log.level)); } /** * Clear all logs */ clearLogs(): void { this.logs = []; this.notifyListeners(); } /** * Subscribe to log updates */ subscribe(listener: (logs: LogEntry[]) => void): () => void { this.listeners.add(listener); return () => this.listeners.delete(listener); } /** * Export logs as text */ exportLogs(): string { return this.logs.map(log => { const time = new Date(log.timestamp).toISOString(); const level = log.level.toUpperCase().padEnd(5); const source = log.source ? ` [${log.source}]` : ''; return `${time} ${level}${source} ${log.message}`; }).join('\n'); } /** * Add a custom log entry */ addCustomLog(level: LogEntry['level'], message: string, data?: any): void { this.addLog(level, message, data); } private notifyListeners(): void { this.listeners.forEach(listener => { try { listener([...this.logs]); } catch (error) { this.originalConsole.error('Error in log listener:', error); } }); } /** * Restore original console methods */ restore(): void { console.log = this.originalConsole.log; console.info = this.originalConsole.info; console.warn = this.originalConsole.warn; console.error = this.originalConsole.error; console.debug = this.originalConsole.debug; } } // Create singleton instance export const logService = new LogService(); // Cleanup on page unload if (typeof window !== 'undefined') { window.addEventListener('beforeunload', () => { logService.restore(); }); }

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/sammcj/bybit-mcp'

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