Microsoft SQL Server MCP Server (MSSQL)

by dperussina
Verified
// lib/logger.js - Logging utilities import winston from 'winston'; import dotenv from 'dotenv'; import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs'; import crypto from 'crypto'; dotenv.config(); // Get the directory name const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Configuration const LOG_LEVEL = process.env.LOG_LEVEL || 'info'; const LOG_FILE = process.env.LOG_FILE || path.join(__dirname, '../logs/mcp-server.log'); const LOG_MAX_SIZE = process.env.LOG_MAX_SIZE || '10m'; const LOG_MAX_FILES = parseInt(process.env.LOG_MAX_FILES) || 5; const LOG_FORMAT = process.env.LOG_FORMAT || 'json'; // Create logs directory if it doesn't exist const logsDir = path.dirname(LOG_FILE); if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir, { recursive: true }); } // Define log formats const logFormats = { console: winston.format.combine( winston.format.colorize(), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf(({ level, message, timestamp, ...metadata }) => { let metaStr = ''; if (Object.keys(metadata).length > 0 && metadata.service !== 'mcp-server') { metaStr = JSON.stringify(metadata); } return `[${timestamp}] ${level}: ${message} ${metaStr}`; }) ), json: winston.format.combine( winston.format.timestamp(), winston.format.json() ), simple: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf(({ level, message, timestamp }) => { return `[${timestamp}] ${level}: ${message}`; }) ) }; // Create Winston logger export const logger = winston.createLogger({ level: LOG_LEVEL, defaultMeta: { service: 'mcp-server' }, format: logFormats[LOG_FORMAT] || logFormats.json, transports: [ // Console transport new winston.transports.Console(), // File transport with rotation new winston.transports.File({ filename: LOG_FILE, maxsize: LOG_MAX_SIZE, maxFiles: LOG_MAX_FILES, tailable: true }) ], exitOnError: false // Don't crash on exception }); // Create a stream object for Morgan HTTP logging export const logStream = { write: message => { logger.http(message.trim()); } }; // Add request context middleware for Express export const addRequestContext = (req, res, next) => { // Add a unique request ID if not present req.id = req.headers['x-request-id'] || crypto.randomUUID(); // Add correlation ID for tracing const correlationId = req.headers['x-correlation-id'] || req.id; // Add request context to logger logger.defaultMeta = { ...logger.defaultMeta, requestId: req.id, correlationId, method: req.method, url: req.url }; // Add response headers for tracing res.setHeader('X-Request-ID', req.id); res.setHeader('X-Correlation-ID', correlationId); next(); }; // Log uncaught exceptions and unhandled rejections process.on('uncaughtException', (error) => { logger.error(`Uncaught Exception: ${error.message}`, { stack: error.stack, name: error.name }); // Exit with error process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled Rejection at:', { promise: promise, reason: reason }); }); // Export logger export default logger;