Skip to main content
Glama
logger.js2.95 kB
/** * Centralized Logging Configuration * Production-ready logging with Winston */ const winston = require('winston'); const path = require('path'); const config = require('../config/config'); // Custom log format const logFormat = winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.json(), winston.format.printf(({ timestamp, level, message, stack, ...meta }) => { const logObject = { timestamp, level, message, ...meta }; if (stack) { logObject.stack = stack; } return JSON.stringify(logObject); }) ); // Console format for development const consoleFormat = winston.format.combine( winston.format.colorize(), winston.format.timestamp({ format: 'HH:mm:ss' }), winston.format.printf(({ timestamp, level, message, ...meta }) => { const metaStr = Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''; return `${timestamp} [${level}]: ${message} ${metaStr}`; }) ); // Create transports array const transports = [ new winston.transports.Console({ format: config.server.env === 'development' ? consoleFormat : logFormat, level: config.logging.level }) ]; // Add file transport if enabled if (config.logging.file.enabled) { // Ensure logs directory exists const fs = require('fs'); const logDir = path.dirname(config.logging.file.filename); if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } transports.push( new winston.transports.File({ filename: config.logging.file.filename, format: logFormat, maxFiles: config.logging.file.maxFiles, maxsize: config.logging.file.maxSize, level: config.logging.level }) ); } // Create logger instance const logger = winston.createLogger({ level: config.logging.level, format: logFormat, transports, exitOnError: false }); // Helper methods for structured logging logger.logRequest = (req, res, responseTime) => { logger.info('HTTP Request', { method: req.method, url: req.url, statusCode: res.statusCode, responseTime: `${responseTime}ms`, userAgent: req.get('User-Agent'), ip: req.ip, contentLength: res.get('Content-Length') }); }; logger.logValidation = (results, processingTime) => { logger.info('Validation completed', { totalDiagrams: results.totalDiagrams, validDiagrams: results.validDiagrams, invalidDiagrams: results.invalidDiagrams, processingTime: `${processingTime}ms`, errorCount: results.results.reduce((acc, r) => acc + r.errors.length, 0) }); }; logger.logError = (error, context = {}) => { logger.error('Application error', { message: error.message, stack: error.stack, ...context }); }; logger.logSecurity = (event, details = {}) => { logger.warn('Security event', { event, ...details }); }; module.exports = logger;

Latest Blog Posts

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/ai-of-mine/fast-mermaid-validator-mcp'

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