• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 14667012576

25 Apr 2025 02:31PM UTC coverage: 81.696%. Remained the same
14667012576

Pull #125

github

fmenezes
fix: duplicated v on version bump
Pull Request #125: fix: duplicated v on version bump

128 of 208 branches covered (61.54%)

Branch coverage included in aggregate %.

720 of 830 relevant lines covered (86.75%)

44.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.85
/src/logger.ts
1
import fs from "fs/promises";
31✔
2
import { MongoLogId, MongoLogManager, MongoLogWriter } from "mongodb-log-writer";
31✔
3
import redact from "mongodb-redact";
31✔
4
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
import { LoggingMessageNotification } from "@modelcontextprotocol/sdk/types.js";
6

7
export type LogLevel = LoggingMessageNotification["params"]["level"];
8

9
abstract class LoggerBase {
10
    abstract log(level: LogLevel, id: MongoLogId, context: string, message: string): void;
11

12
    info(id: MongoLogId, context: string, message: string): void {
13
        this.log("info", id, context, message);
27✔
14
    }
15

16
    error(id: MongoLogId, context: string, message: string): void {
17
        this.log("error", id, context, message);
30✔
18
    }
19
    debug(id: MongoLogId, context: string, message: string): void {
20
        this.log("debug", id, context, message);
229✔
21
    }
22

23
    notice(id: MongoLogId, context: string, message: string): void {
24
        this.log("notice", id, context, message);
×
25
    }
26

27
    warning(id: MongoLogId, context: string, message: string): void {
28
        this.log("warning", id, context, message);
×
29
    }
30

31
    critical(id: MongoLogId, context: string, message: string): void {
32
        this.log("critical", id, context, message);
×
33
    }
34

35
    alert(id: MongoLogId, context: string, message: string): void {
36
        this.log("alert", id, context, message);
×
37
    }
38

39
    emergency(id: MongoLogId, context: string, message: string): void {
40
        this.log("emergency", id, context, message);
×
41
    }
42
}
43

44
class ConsoleLogger extends LoggerBase {
45
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
46
        message = redact(message);
×
47
        console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message}`);
×
48
    }
49
}
50

51
class DiskLogger extends LoggerBase {
52
    private constructor(private logWriter: MongoLogWriter) {
27✔
53
        super();
27✔
54
    }
55

56
    static async fromPath(logPath: string): Promise<DiskLogger> {
57
        await fs.mkdir(logPath, { recursive: true });
27✔
58

59
        const manager = new MongoLogManager({
27✔
60
            directory: logPath,
61
            retentionDays: 30,
62
            onwarn: console.warn,
63
            onerror: console.error,
64
            gzip: false,
65
            retentionGB: 1,
66
        });
67

68
        await manager.cleanupOldLogFiles();
27✔
69

70
        const logWriter = await manager.createLogWriter();
27✔
71

72
        return new DiskLogger(logWriter);
27✔
73
    }
74

75
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
76
        message = redact(message);
286✔
77
        const mongoDBLevel = this.mapToMongoDBLogLevel(level);
286✔
78

79
        this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message);
286✔
80
    }
81

82
    private mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
83
        switch (level) {
286!
84
            case "info":
85
                return "info";
27✔
86
            case "warning":
87
                return "warn";
×
88
            case "error":
89
                return "error";
30✔
90
            case "notice":
91
            case "debug":
92
                return "debug";
229✔
93
            case "critical":
94
            case "alert":
95
            case "emergency":
96
                return "fatal";
×
97
            default:
98
                return "info";
×
99
        }
100
    }
101
}
102

103
class McpLogger extends LoggerBase {
104
    constructor(private server: McpServer) {
27✔
105
        super();
27✔
106
    }
107

108
    log(level: LogLevel, _: MongoLogId, context: string, message: string): void {
109
        void this.server.server.sendLoggingMessage({
286✔
110
            level,
111
            data: `[${context}]: ${message}`,
112
        });
113
    }
114
}
115

116
class CompositeLogger extends LoggerBase {
117
    private loggers: LoggerBase[];
118

119
    constructor(...loggers: LoggerBase[]) {
120
        super();
31✔
121

122
        if (loggers.length === 0) {
31✔
123
            // default to ConsoleLogger
124
            this.loggers = [new ConsoleLogger()];
31✔
125
            return;
31✔
126
        }
127

128
        this.loggers = [...loggers];
×
129
    }
130

131
    setLoggers(...loggers: LoggerBase[]): void {
132
        if (loggers.length === 0) {
27!
133
            throw new Error("At least one logger must be provided");
×
134
        }
135
        this.loggers = [...loggers];
27✔
136
    }
137

138
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
139
        for (const logger of this.loggers) {
286✔
140
            logger.log(level, id, context, message);
572✔
141
        }
142
    }
143
}
144

145
const logger = new CompositeLogger();
31✔
146
export default logger;
31✔
147

148
export async function initializeLogger(server: McpServer, logPath: string): Promise<LoggerBase> {
31✔
149
    const diskLogger = await DiskLogger.fromPath(logPath);
27✔
150
    const mcpLogger = new McpLogger(server);
27✔
151

152
    logger.setLoggers(mcpLogger, diskLogger);
27✔
153

154
    return logger;
27✔
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc