@@ -7,7 +7,12 @@ import { LoggingMessageNotification } from "@modelcontextprotocol/sdk/types.js";
77export type LogLevel = LoggingMessageNotification [ "params" ] [ "level" ] ;
88
99abstract 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