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

mongodb-js / mongodb-mcp-server / 14714557796

28 Apr 2025 05:59PM UTC coverage: 82.713%. First build
14714557796

Pull #151

github

blva
chore: default telemetry
Pull Request #151: chore: default telemetry

142 of 235 branches covered (60.43%)

Branch coverage included in aggregate %.

791 of 893 relevant lines covered (88.58%)

48.19 hits per line

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

73.85
/src/logger.ts
1
import fs from "fs/promises";
33✔
2
import { mongoLogId, MongoLogId, MongoLogManager, MongoLogWriter } from "mongodb-log-writer";
33✔
3
import redact from "mongodb-redact";
33✔
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
export const LogId = {
33✔
10
    serverStartFailure: mongoLogId(1_000_001),
11
    serverInitialized: mongoLogId(1_000_002),
12

13
    atlasCheckCredentials: mongoLogId(1_001_001),
14
    atlasDeleteDatabaseUserFailure: mongoLogId(1_001_002),
15

16
    telemetryDisabled: mongoLogId(1_002_001),
17
    telemetryEmitFailure: mongoLogId(1_002_002),
18
    telemetryEmitStart: mongoLogId(1_002_003),
19
    telemetryEmitSuccess: mongoLogId(1_002_004),
20

21
    toolExecute: mongoLogId(1_003_001),
22
    toolExecuteFailure: mongoLogId(1_003_002),
23
    toolDisabled: mongoLogId(1_003_003),
24

25
    mongodbConnectFailure: mongoLogId(1_004_001),
26
    mongodbDisconnectFailure: mongoLogId(1_004_002),
27
} as const;
28

29
abstract class LoggerBase {
30
    abstract log(level: LogLevel, id: MongoLogId, context: string, message: string): void;
31

32
    info(id: MongoLogId, context: string, message: string): void {
33
        this.log("info", id, context, message);
27✔
34
    }
35

36
    error(id: MongoLogId, context: string, message: string): void {
37
        this.log("error", id, context, message);
6✔
38
    }
39
    debug(id: MongoLogId, context: string, message: string): void {
40
        this.log("debug", id, context, message);
401✔
41
    }
42

43
    notice(id: MongoLogId, context: string, message: string): void {
44
        this.log("notice", id, context, message);
×
45
    }
46

47
    warning(id: MongoLogId, context: string, message: string): void {
48
        this.log("warning", id, context, message);
×
49
    }
50

51
    critical(id: MongoLogId, context: string, message: string): void {
52
        this.log("critical", id, context, message);
×
53
    }
54

55
    alert(id: MongoLogId, context: string, message: string): void {
56
        this.log("alert", id, context, message);
×
57
    }
58

59
    emergency(id: MongoLogId, context: string, message: string): void {
60
        this.log("emergency", id, context, message);
×
61
    }
62
}
63

64
class ConsoleLogger extends LoggerBase {
65
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
66
        message = redact(message);
12✔
67
        console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message}`);
12✔
68
    }
69
}
70

71
class DiskLogger extends LoggerBase {
72
    private constructor(private logWriter: MongoLogWriter) {
27✔
73
        super();
27✔
74
    }
75

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

79
        const manager = new MongoLogManager({
27✔
80
            directory: logPath,
81
            retentionDays: 30,
82
            onwarn: console.warn,
83
            onerror: console.error,
84
            gzip: false,
85
            retentionGB: 1,
86
        });
87

88
        await manager.cleanupOldLogFiles();
27✔
89

90
        const logWriter = await manager.createLogWriter();
27✔
91

92
        return new DiskLogger(logWriter);
27✔
93
    }
94

95
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
96
        message = redact(message);
422✔
97
        const mongoDBLevel = this.mapToMongoDBLogLevel(level);
422✔
98

99
        this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message);
422✔
100
    }
101

102
    private mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
103
        switch (level) {
422!
104
            case "info":
105
                return "info";
27✔
106
            case "warning":
107
                return "warn";
×
108
            case "error":
109
                return "error";
6✔
110
            case "notice":
111
            case "debug":
112
                return "debug";
389✔
113
            case "critical":
114
            case "alert":
115
            case "emergency":
116
                return "fatal";
×
117
            default:
118
                return "info";
×
119
        }
120
    }
121
}
122

123
class McpLogger extends LoggerBase {
124
    constructor(private server: McpServer) {
27✔
125
        super();
27✔
126
    }
127

128
    log(level: LogLevel, _: MongoLogId, context: string, message: string): void {
129
        // Only log if the server is connected
130
        if (!this.server?.isConnected()) {
422✔
131
            return;
40✔
132
        }
133

134
        void this.server.server.sendLoggingMessage({
382✔
135
            level,
136
            data: `[${context}]: ${message}`,
137
        });
138
    }
139
}
140

141
class CompositeLogger extends LoggerBase {
142
    private loggers: LoggerBase[];
143

144
    constructor(...loggers: LoggerBase[]) {
145
        super();
33✔
146

147
        if (loggers.length === 0) {
33✔
148
            // default to ConsoleLogger
149
            this.loggers = [new ConsoleLogger()];
33✔
150
            return;
33✔
151
        }
152

153
        this.loggers = [...loggers];
×
154
    }
155

156
    setLoggers(...loggers: LoggerBase[]): void {
157
        if (loggers.length === 0) {
27!
158
            throw new Error("At least one logger must be provided");
×
159
        }
160
        this.loggers = [...loggers];
27✔
161
    }
162

163
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
164
        for (const logger of this.loggers) {
434✔
165
            logger.log(level, id, context, message);
856✔
166
        }
167
    }
168
}
169

170
const logger = new CompositeLogger();
33✔
171
export default logger;
33✔
172

173
export async function initializeLogger(server: McpServer, logPath: string): Promise<LoggerBase> {
33✔
174
    const diskLogger = await DiskLogger.fromPath(logPath);
27✔
175
    const mcpLogger = new McpLogger(server);
27✔
176

177
    logger.setLoggers(mcpLogger, diskLogger);
27✔
178

179
    return logger;
27✔
180
}
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

© 2026 Coveralls, Inc