Skip to main content
Glama
logger.ts2.83 kB
/** * Logger utility for PartnerCore Proxy * * Security: This logger automatically masks sensitive data like API keys, * passwords, and tokens to prevent accidental exposure in logs. */ import winston from 'winston'; let loggerInstance: winston.Logger | null = null; /** * Patterns that indicate sensitive data in log messages */ const SENSITIVE_PATTERNS = [ // API keys and tokens /api[_-]?key[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi, /token[=:]\s*['"]?([a-zA-Z0-9_.-]{20,})['"]?/gi, /bearer\s+([a-zA-Z0-9_.-]{20,})/gi, /authorization[=:]\s*['"]?([a-zA-Z0-9_.-]{20,})['"]?/gi, // Passwords /password[=:]\s*['"]?([^\s'"]+)['"]?/gi, /secret[=:]\s*['"]?([^\s'"]+)['"]?/gi, ]; /** * Mask sensitive data in a string */ function maskSensitiveString(str: string): string { let masked = str; for (const pattern of SENSITIVE_PATTERNS) { masked = masked.replace(pattern, (match: string, group: string | undefined) => { const capturedGroup = group ?? ''; if (capturedGroup.length > 8) { return match.replace(capturedGroup, `${capturedGroup.slice(0, 4)}****${capturedGroup.slice(-4)}`); } return match.replace(capturedGroup || match, '****'); }); } return masked; } /** * Format for masking sensitive data */ const maskSensitiveFormat = winston.format((info) => { if (typeof info.message === 'string') { info.message = maskSensitiveString(info.message); } return info; }); /** * Create and configure the logger */ export function createLogger(level: string = 'info'): winston.Logger { if (loggerInstance) { return loggerInstance; } loggerInstance = winston.createLogger({ level, format: winston.format.combine( maskSensitiveFormat(), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.printf(({ level, message, timestamp, ...meta }) => { // Mask sensitive data in metadata too let metaStr = ''; if (Object.keys(meta).length) { const maskedMeta = maskSensitiveString(JSON.stringify(meta)); metaStr = ` ${maskedMeta}`; } const ts = String(timestamp ?? ''); const msg = String(message ?? ''); return `[${ts}] ${level.toUpperCase()}: ${msg}${metaStr}`; }) ), transports: [ new winston.transports.Console({ stderrLevels: ['error', 'warn'], }), ], }); return loggerInstance; } /** * Get the logger instance (creates one if not exists) */ export function getLogger(): winston.Logger { if (!loggerInstance) { return createLogger(); } return loggerInstance; } /** * Set log level dynamically */ export function setLogLevel(level: string): void { const logger = getLogger(); logger.level = level; }

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/ciellosinc/partnercore-proxy'

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