UNPKG

ntfy-mcp-server

Version:

An MCP (Model Context Protocol) server designed to interact with the ntfy push notification service. It enables LLMs and AI agents to send notifications to your devices with extensive customization options.

93 lines (92 loc) 3.54 kB
import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; import winston from "winston"; // Handle ESM module dirname const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Resolve logs directory relative to project root (2 levels up from utils/) const projectRoot = path.resolve(__dirname, '..', '..'); const logsDir = path.join(projectRoot, 'logs'); class Logger { constructor() { const logLevel = process.env.LOG_LEVEL || "info"; // Ensure logs directory exists if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir, { recursive: true }); } // Common format for all transports const commonFormat = winston.format.combine(winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.printf(({ timestamp, level, message, context, stack }) => { const contextStr = context ? `\n Context: ${JSON.stringify(context, null, 2)}` : ""; const stackStr = stack ? `\n Stack: ${stack}` : ""; return `[${timestamp}] ${level}: ${message}${contextStr}${stackStr}`; })); this.logger = winston.createLogger({ level: logLevel, format: winston.format.json(), transports: [ // Combined log file for all levels new winston.transports.File({ filename: path.join(logsDir, 'combined.log'), format: commonFormat }), // Separate log files for each level new winston.transports.File({ filename: path.join(logsDir, 'error.log'), level: 'error', format: commonFormat }), new winston.transports.File({ filename: path.join(logsDir, 'warn.log'), level: 'warn', format: commonFormat }), new winston.transports.File({ filename: path.join(logsDir, 'info.log'), level: 'info', format: commonFormat }), new winston.transports.File({ filename: path.join(logsDir, 'debug.log'), level: 'debug', format: commonFormat }) ] }); } static getInstance() { if (!Logger.instance) { Logger.instance = new Logger(); } return Logger.instance; } debug(message, context) { this.logger.debug(message, { context }); } info(message, context) { this.logger.info(message, { context }); } warn(message, context) { this.logger.warn(message, { context }); } error(message, context) { this.logger.error(message, { context }); } createChildLogger(metadata) { return { debug: (message, context) => { this.debug(`[${metadata.module}] ${message}`, context); }, info: (message, context) => { this.info(`[${metadata.module}] ${message}`, context); }, warn: (message, context) => { this.warn(`[${metadata.module}] ${message}`, context); }, error: (message, context) => { this.error(`[${metadata.module}] ${message}`, context); } }; } } export const logger = Logger.getInstance();