| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /**
- * 日志工具模块
- *
- * 支持不同级别的日志记录(info, error, warn, debug)
- * 优先通过 MCP 协议的日志通知功能发送日志,如果 MCP Server 不可用则回退到 console.error
- */
- const LOG_LEVELS = {
- DEBUG: 0,
- INFO: 1,
- WARN: 2,
- ERROR: 3,
- };
- // MCP 日志级别映射
- const MCP_LOG_LEVELS = {
- DEBUG: 'debug',
- INFO: 'info',
- WARN: 'warning',
- ERROR: 'error',
- };
- // 从环境变量获取日志级别,默认为 INFO
- const getLogLevel = () => {
- const level = process.env.LOG_LEVEL?.toUpperCase() || 'INFO';
- return LOG_LEVELS[level] ?? LOG_LEVELS.INFO;
- };
- const currentLogLevel = getLogLevel();
- // 全局 MCP Server 实例(由 index.js 设置)
- let mcpServer = null;
- /**
- * 设置 MCP Server 实例,用于发送日志通知
- */
- export function setMcpServer(server) {
- mcpServer = server;
- }
- /**
- * 通过 MCP 协议发送日志通知
- * 根据 MCP 协议规范,日志通知应该通过 stdout 以 JSON-RPC 通知消息的形式发送
- * 同时也会输出到 stderr 作为备份,确保日志始终可见
- */
- function sendLogToMcp(level, message) {
- if (mcpServer) {
- try {
- // MCP 协议的日志通知格式:通过 stdout 发送 JSON-RPC 通知消息
- // 格式:{"jsonrpc": "2.0", "method": "notifications/message", "params": {"level": "info", "message": "..."}}
- const logNotification = {
- jsonrpc: '2.0',
- method: 'notifications/message',
- params: {
- level: MCP_LOG_LEVELS[level] || 'info',
- message: message,
- },
- };
- // 输出 JSON-RPC 格式的日志通知到 stdout(MCP 协议的标准方式)
- // 注意:必须以换行符结尾,并且是有效的 JSON
- console.log(JSON.stringify(logNotification));
- // 同时输出到 stderr 作为备份,确保日志始终可见
- // 这样即使 MCP 客户端没有正确处理通知,日志也能在 stderr 中看到
- console.error(formatLogMessage(level, message));
- return true;
- } catch (error) {
- // 如果发送失败,回退到 stderr 输出(普通格式)
- console.error(`[${level}] Failed to send log via MCP: ${error.message}`);
- return false;
- }
- }
- return false;
- }
- /**
- * 格式化日志消息
- * 不包含时间戳,因为 Cursor 会自动添加
- */
- function formatLogMessage(level, message) {
- return `[${level}] ${message}`;
- }
- /**
- * 记录 INFO 级别的日志(正常操作信息)
- * 优先通过 MCP 协议格式发送,同时也会输出到 stderr 确保可见
- */
- export function info(message) {
- if (currentLogLevel <= LOG_LEVELS.INFO) {
- // 尝试通过 MCP 协议格式发送日志(同时会输出到 stderr 作为备份)
- const sent = sendLogToMcp('INFO', message);
- if (!sent) {
- // 如果 MCP Server 不可用,回退到 stderr 输出(普通格式)
- console.error(formatLogMessage('INFO', message));
- }
- }
- }
- /**
- * 记录 ERROR 级别的日志(错误信息)
- */
- export function error(message) {
- if (currentLogLevel <= LOG_LEVELS.ERROR) {
- const sent = sendLogToMcp('ERROR', message);
- if (!sent) {
- console.error(formatLogMessage('ERROR', message));
- }
- }
- }
- /**
- * 记录 WARN 级别的日志(警告信息)
- */
- export function warn(message) {
- if (currentLogLevel <= LOG_LEVELS.WARN) {
- const sent = sendLogToMcp('WARN', message);
- if (!sent) {
- console.error(formatLogMessage('WARN', message));
- }
- }
- }
- /**
- * 记录 DEBUG 级别的日志(调试信息)
- */
- export function debug(message) {
- if (currentLogLevel <= LOG_LEVELS.DEBUG) {
- const sent = sendLogToMcp('DEBUG', message);
- if (!sent) {
- console.error(formatLogMessage('DEBUG', message));
- }
- }
- }
|