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

mongodb-js / mongodb-mcp-server / 16449784595

22 Jul 2025 04:14PM UTC coverage: 80.241% (-1.6%) from 81.82%
16449784595

Pull #387

github

web-flow
Merge f1f43f97f into f8e500004
Pull Request #387: chore: update JIRA automation

564 of 739 branches covered (76.32%)

Branch coverage included in aggregate %.

3099 of 3826 relevant lines covered (81.0%)

47.23 hits per line

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

87.36
/src/common/logger.ts
1
import fs from "fs/promises";
2✔
2
import { mongoLogId, MongoLogId, MongoLogManager, MongoLogWriter } from "mongodb-log-writer";
2✔
3
import redact from "mongodb-redact";
2✔
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 = {
2✔
10
    serverStartFailure: mongoLogId(1_000_001),
2✔
11
    serverInitialized: mongoLogId(1_000_002),
2✔
12
    serverCloseRequested: mongoLogId(1_000_003),
2✔
13
    serverClosed: mongoLogId(1_000_004),
2✔
14
    serverCloseFailure: mongoLogId(1_000_005),
2✔
15
    serverDuplicateLoggers: mongoLogId(1_000_006),
2✔
16

17
    atlasCheckCredentials: mongoLogId(1_001_001),
2✔
18
    atlasDeleteDatabaseUserFailure: mongoLogId(1_001_002),
2✔
19
    atlasConnectFailure: mongoLogId(1_001_003),
2✔
20
    atlasInspectFailure: mongoLogId(1_001_004),
2✔
21
    atlasConnectAttempt: mongoLogId(1_001_005),
2✔
22
    atlasConnectSucceeded: mongoLogId(1_001_006),
2✔
23
    atlasApiRevokeFailure: mongoLogId(1_001_007),
2✔
24
    atlasIpAccessListAdded: mongoLogId(1_001_008),
2✔
25
    atlasIpAccessListAddFailure: mongoLogId(1_001_009),
2✔
26

27
    telemetryDisabled: mongoLogId(1_002_001),
2✔
28
    telemetryEmitFailure: mongoLogId(1_002_002),
2✔
29
    telemetryEmitStart: mongoLogId(1_002_003),
2✔
30
    telemetryEmitSuccess: mongoLogId(1_002_004),
2✔
31
    telemetryMetadataError: mongoLogId(1_002_005),
2✔
32
    telemetryDeviceIdFailure: mongoLogId(1_002_006),
2✔
33
    telemetryDeviceIdTimeout: mongoLogId(1_002_007),
2✔
34

35
    toolExecute: mongoLogId(1_003_001),
2✔
36
    toolExecuteFailure: mongoLogId(1_003_002),
2✔
37
    toolDisabled: mongoLogId(1_003_003),
2✔
38

39
    mongodbConnectFailure: mongoLogId(1_004_001),
2✔
40
    mongodbDisconnectFailure: mongoLogId(1_004_002),
2✔
41

42
    toolUpdateFailure: mongoLogId(1_005_001),
2✔
43

44
    streamableHttpTransportStarted: mongoLogId(1_006_001),
2✔
45
    streamableHttpTransportSessionCloseFailure: mongoLogId(1_006_002),
2✔
46
    streamableHttpTransportSessionCloseNotification: mongoLogId(1_006_003),
2✔
47
    streamableHttpTransportSessionCloseNotificationFailure: mongoLogId(1_006_004),
2✔
48
    streamableHttpTransportRequestFailure: mongoLogId(1_006_005),
2✔
49
    streamableHttpTransportCloseFailure: mongoLogId(1_006_006),
2✔
50
} as const;
2✔
51

52
export abstract class LoggerBase {
2✔
53
    abstract log(level: LogLevel, id: MongoLogId, context: string, message: string): void;
54

55
    info(id: MongoLogId, context: string, message: string): void {
2✔
56
        this.log("info", id, context, message);
262✔
57
    }
262✔
58

59
    error(id: MongoLogId, context: string, message: string): void {
2✔
60
        this.log("error", id, context, message);
73✔
61
    }
73✔
62
    debug(id: MongoLogId, context: string, message: string): void {
2✔
63
        this.log("debug", id, context, message);
583✔
64
    }
583✔
65

66
    notice(id: MongoLogId, context: string, message: string): void {
2✔
67
        this.log("notice", id, context, message);
×
68
    }
×
69

70
    warning(id: MongoLogId, context: string, message: string): void {
2✔
71
        this.log("warning", id, context, message);
×
72
    }
×
73

74
    critical(id: MongoLogId, context: string, message: string): void {
2✔
75
        this.log("critical", id, context, message);
×
76
    }
×
77

78
    alert(id: MongoLogId, context: string, message: string): void {
2✔
79
        this.log("alert", id, context, message);
×
80
    }
×
81

82
    emergency(id: MongoLogId, context: string, message: string): void {
2✔
83
        this.log("emergency", id, context, message);
×
84
    }
×
85
}
2✔
86

87
export class ConsoleLogger extends LoggerBase {
2✔
88
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
2✔
89
        message = redact(message);
883✔
90
        console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message} (${process.pid})`);
883✔
91
    }
883✔
92
}
2✔
93

94
export class DiskLogger extends LoggerBase {
2✔
95
    private constructor(private logWriter: MongoLogWriter) {
2✔
96
        super();
4✔
97
    }
4✔
98

99
    static async fromPath(logPath: string): Promise<DiskLogger> {
2✔
100
        await fs.mkdir(logPath, { recursive: true });
4✔
101

102
        const manager = new MongoLogManager({
4✔
103
            directory: logPath,
4✔
104
            retentionDays: 30,
4✔
105
            onwarn: console.warn,
4✔
106
            onerror: console.error,
4✔
107
            gzip: false,
4✔
108
            retentionGB: 1,
4✔
109
        });
4✔
110

111
        await manager.cleanupOldLogFiles();
4✔
112

113
        const logWriter = await manager.createLogWriter();
4✔
114

115
        return new DiskLogger(logWriter);
4✔
116
    }
4✔
117

118
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
2✔
119
        message = redact(message);
35✔
120
        const mongoDBLevel = this.mapToMongoDBLogLevel(level);
35✔
121

122
        this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message);
35✔
123
    }
35✔
124

125
    private mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
2✔
126
        switch (level) {
35✔
127
            case "info":
35✔
128
                return "info";
16✔
129
            case "warning":
35!
130
                return "warn";
×
131
            case "error":
35✔
132
                return "error";
4✔
133
            case "notice":
35!
134
            case "debug":
35✔
135
                return "debug";
15✔
136
            case "critical":
35!
137
            case "alert":
35!
138
            case "emergency":
35!
139
                return "fatal";
×
140
            default:
35!
141
                return "info";
×
142
        }
35✔
143
    }
35✔
144
}
2✔
145

146
export class McpLogger extends LoggerBase {
2✔
147
    constructor(private server: McpServer) {
2✔
148
        super();
6✔
149
    }
6✔
150

151
    log(level: LogLevel, _: MongoLogId, context: string, message: string): void {
2✔
152
        // Only log if the server is connected
153
        if (!this.server?.isConnected()) {
35✔
154
            return;
7✔
155
        }
7✔
156

157
        void this.server.server.sendLoggingMessage({
28✔
158
            level,
28✔
159
            data: `[${context}]: ${message}`,
28✔
160
        });
28✔
161
    }
35✔
162
}
2✔
163

164
class CompositeLogger extends LoggerBase {
2✔
165
    private loggers: LoggerBase[] = [];
2✔
166

167
    constructor(...loggers: LoggerBase[]) {
2✔
168
        super();
70✔
169

170
        this.setLoggers(...loggers);
70✔
171
    }
70✔
172

173
    setLoggers(...loggers: LoggerBase[]): void {
2✔
174
        if (loggers.length === 0) {
134!
175
            throw new Error("At least one logger must be provided");
×
176
        }
×
177
        this.loggers = [...loggers];
134✔
178
    }
134✔
179

180
    log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
2✔
181
        for (const logger of this.loggers) {
918✔
182
            logger.log(level, id, context, message);
953✔
183
        }
953✔
184
    }
918✔
185
}
2✔
186

187
const logger = new CompositeLogger(new ConsoleLogger());
2✔
188
export default logger;
2✔
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