Files
kicad-mcp-server/src/logger.ts
Eugene Mikhantyev 7d50fa1d4c style: apply Prettier formatting to TS/JS/JSON/MD files
Add Prettier as a dev dependency with .prettierrc.json config and
.prettierignore. Hook added via mirrors-prettier in pre-commit config.
All TypeScript, JSON, Markdown, and YAML files auto-formatted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:05:50 +01:00

115 lines
2.8 KiB
TypeScript

/**
* Logger for KiCAD MCP server
*/
import { existsSync, mkdirSync, appendFileSync } from "fs";
import { join } from "path";
import * as os from "os";
// Log levels
type LogLevel = "error" | "warn" | "info" | "debug";
// Default log directory
const DEFAULT_LOG_DIR = join(os.homedir(), ".kicad-mcp", "logs");
/**
* Logger class for KiCAD MCP server
*/
class Logger {
private logLevel: LogLevel = "info";
private logDir: string = DEFAULT_LOG_DIR;
/**
* Set the log level
* @param level Log level to set
*/
setLogLevel(level: LogLevel): void {
this.logLevel = level;
}
/**
* Set the log directory
* @param dir Directory to store log files
*/
setLogDir(dir: string): void {
this.logDir = dir;
// Ensure log directory exists
if (!existsSync(this.logDir)) {
mkdirSync(this.logDir, { recursive: true });
}
}
/**
* Log an error message
* @param message Message to log
*/
error(message: string): void {
this.log("error", message);
}
/**
* Log a warning message
* @param message Message to log
*/
warn(message: string): void {
if (["error", "warn", "info", "debug"].includes(this.logLevel)) {
this.log("warn", message);
}
}
/**
* Log an info message
* @param message Message to log
*/
info(message: string): void {
if (["info", "debug"].includes(this.logLevel)) {
this.log("info", message);
}
}
/**
* Log a debug message
* @param message Message to log
*/
debug(message: string): void {
if (this.logLevel === "debug") {
this.log("debug", message);
}
}
/**
* Log a message with the specified level
* @param level Log level
* @param message Message to log
*/
private log(level: LogLevel, message: string): void {
const now = new Date();
const pad = (n: number, w = 2) => String(n).padStart(w, "0");
const timestamp =
`${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ` +
`${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())},${pad(now.getMilliseconds(), 3)}`;
const formattedMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
// Log to console.error (stderr) only - stdout is reserved for MCP protocol
// All log levels go to stderr to avoid corrupting STDIO MCP transport
console.error(formattedMessage);
// Log to file
try {
// Ensure log directory exists
if (!existsSync(this.logDir)) {
mkdirSync(this.logDir, { recursive: true });
}
const logFile = join(this.logDir, `kicad-mcp-${new Date().toISOString().split("T")[0]}.log`);
appendFileSync(logFile, formattedMessage + "\n");
} catch (error) {
console.error(`Failed to write to log file: ${error}`);
}
}
}
// Create and export logger instance
export const logger = new Logger();