mcp-framework
Version:
Framework for building Model Context Protocol (MCP) servers in Typescript
91 lines (90 loc) • 2.99 kB
JavaScript
import { createWriteStream } from "fs";
import { join } from "path";
import { mkdir } from "fs/promises";
export class Logger {
static instance;
logStream = null;
logFilePath = '';
logToFile = false;
constructor() {
this.logToFile = process.env.MCP_ENABLE_FILE_LOGGING === 'true';
if (this.logToFile) {
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
const logDir = process.env.MCP_LOG_DIRECTORY || "logs";
this.initFileLogging(logDir, timestamp);
}
process.on("exit", () => this.close());
process.on("SIGINT", () => this.close());
process.on("SIGTERM", () => this.close());
}
async initFileLogging(logDir, timestamp) {
try {
await mkdir(logDir, { recursive: true });
this.logFilePath = join(logDir, `mcp-server-${timestamp}.log`);
this.logStream = createWriteStream(this.logFilePath, { flags: "a" });
this.info(`File logging enabled, writing to: ${this.logFilePath}`);
}
catch (err) {
process.stderr.write(`Failed to initialize file logging: ${err}\n`);
this.logToFile = false;
}
}
static getInstance() {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
getTimestamp() {
return new Date().toISOString();
}
formatMessage(level, message) {
return `[${this.getTimestamp()}] [${level}] ${message}\n`;
}
info(message) {
const formattedMessage = this.formatMessage("INFO", message);
if (this.logToFile && this.logStream) {
this.logStream.write(formattedMessage);
}
process.stderr.write(formattedMessage);
}
log(message) {
this.info(message);
}
error(message) {
const formattedMessage = this.formatMessage("ERROR", message);
if (this.logToFile && this.logStream) {
this.logStream.write(formattedMessage);
}
process.stderr.write(formattedMessage);
}
warn(message) {
const formattedMessage = this.formatMessage("WARN", message);
if (this.logToFile && this.logStream) {
this.logStream.write(formattedMessage);
}
process.stderr.write(formattedMessage);
}
debug(message) {
const formattedMessage = this.formatMessage("DEBUG", message);
if (this.logToFile && this.logStream) {
this.logStream.write(formattedMessage);
}
if (process.env.MCP_DEBUG_CONSOLE === 'true') {
process.stderr.write(formattedMessage);
}
}
close() {
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
}
getLogPath() {
return this.logFilePath;
}
isFileLoggingEnabled() {
return this.logToFile;
}
}
export const logger = Logger.getInstance();