Skip to content

Commit 8841667

Browse files
committed
refactor: split loggers
1 parent 937b933 commit 8841667

File tree

1 file changed

+76
-26
lines changed

1 file changed

+76
-26
lines changed

src/logger.ts

Lines changed: 76 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ import { LoggingMessageNotification } from "@modelcontextprotocol/sdk/types.js";
77
export type LogLevel = LoggingMessageNotification["params"]["level"];
88

99
abstract class LoggerBase {
10+
async initialize(): Promise<void> {
11+
return Promise.resolve();
12+
}
13+
1014
abstract log(level: LogLevel, id: MongoLogId, context: string, message: string): void;
15+
1116
info(id: MongoLogId, context: string, message: string): void {
1217
this.log("info", id, context, message);
1318
}
@@ -47,22 +52,41 @@ class ConsoleLogger extends LoggerBase {
4752
}
4853
}
4954

50-
class Logger extends LoggerBase {
55+
class DiskLogger extends LoggerBase {
56+
private logWriter?: MongoLogWriter;
57+
5158
constructor(
52-
private logWriter: MongoLogWriter,
53-
private server: McpServer
59+
private logPath: string
5460
) {
5561
super();
5662
}
5763

64+
async initialize(): Promise<void> {
65+
await fs.mkdir(this.logPath, { recursive: true });
66+
67+
const manager = new MongoLogManager({
68+
directory: this.logPath,
69+
retentionDays: 30,
70+
onwarn: console.warn,
71+
onerror: console.error,
72+
gzip: false,
73+
retentionGB: 1,
74+
});
75+
76+
await manager.cleanupOldLogFiles();
77+
78+
this.logWriter = await manager.createLogWriter();
79+
}
80+
5881
log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
5982
message = redact(message);
6083
const mongoDBLevel = this.mapToMongoDBLogLevel(level);
84+
85+
if (!this.logWriter) {
86+
throw new Error("DiskLogger is not initialized");
87+
}
88+
6189
this.logWriter[mongoDBLevel]("MONGODB-MCP", id, context, message);
62-
void this.server.server.sendLoggingMessage({
63-
level,
64-
data: `[${context}]: ${message}`,
65-
});
6690
}
6791

6892
private mapToMongoDBLogLevel(level: LogLevel): "info" | "warn" | "error" | "debug" | "fatal" {
@@ -86,31 +110,57 @@ class Logger extends LoggerBase {
86110
}
87111
}
88112

89-
class ProxyingLogger extends LoggerBase {
90-
private internalLogger: LoggerBase = new ConsoleLogger();
91113

92-
log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
93-
this.internalLogger.log(level, id, context, message);
114+
class McpLogger extends LoggerBase {
115+
constructor(
116+
private server: McpServer
117+
) {
118+
super();
119+
}
120+
121+
log(level: LogLevel, _: MongoLogId, context: string, message: string): void {
122+
void this.server.server.sendLoggingMessage({
123+
level,
124+
data: `[${context}]: ${message}`,
125+
});
94126
}
95127
}
96128

97-
const logger = new ProxyingLogger();
98-
export default logger;
129+
class CompositeLogger extends LoggerBase {
130+
private loggers: LoggerBase[];
99131

100-
export async function initializeLogger(server: McpServer, logPath: string): Promise<void> {
101-
await fs.mkdir(logPath, { recursive: true });
132+
constructor(...loggers: LoggerBase[]) {
133+
super();
134+
if (loggers.length === 0) { // default to ConsoleLogger
135+
loggers.push(new ConsoleLogger());
136+
}
137+
this.loggers = [...loggers];
138+
}
102139

103-
const manager = new MongoLogManager({
104-
directory: logPath,
105-
retentionDays: 30,
106-
onwarn: console.warn,
107-
onerror: console.error,
108-
gzip: false,
109-
retentionGB: 1,
110-
});
140+
async initialize(): Promise<void> {
141+
for(const logger of this.loggers) {
142+
await logger.initialize();
143+
}
144+
}
111145

112-
await manager.cleanupOldLogFiles();
146+
setLoggers(...loggers: LoggerBase[]): void {
147+
this.loggers = [...loggers];
148+
}
149+
150+
log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
151+
for(const logger of this.loggers) {
152+
logger.log(level, id, context, message);
153+
}
154+
}
155+
}
113156

114-
const logWriter = await manager.createLogWriter();
115-
logger["internalLogger"] = new Logger(logWriter, server);
157+
const logger = new CompositeLogger();
158+
export default logger;
159+
160+
export async function initializeLogger(server: McpServer, logPath: string): Promise<void> {
161+
logger.setLoggers(
162+
new McpLogger(server),
163+
new DiskLogger(logPath),
164+
)
165+
await logger.initialize();
116166
}

0 commit comments

Comments
 (0)