@@ -3,10 +3,103 @@ import path from "path";
33import config from "./config.js" ;
44import redact from "mongodb-redact" ;
55import fs from "fs/promises" ;
6+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ;
7+ import { LoggingMessageNotification } from "@modelcontextprotocol/sdk/types.js" ;
68
7- let logWriter : MongoLogWriter | undefined = undefined ;
9+ export type LogLevel = LoggingMessageNotification [ "params" ] [ "level" ] ;
810
9- export async function initializeLogger ( ) : Promise < void > {
11+ abstract class LoggerBase {
12+ abstract log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void ;
13+ info ( id : MongoLogId , context : string , message : string ) : void {
14+ this . log ( "info" , id , context , message ) ;
15+ }
16+
17+ error ( id : MongoLogId , context : string , message : string ) : void {
18+ this . log ( "error" , id , context , message ) ;
19+ }
20+ debug ( id : MongoLogId , context : string , message : string ) : void {
21+ this . log ( "debug" , id , context , message ) ;
22+ }
23+
24+ notice ( id : MongoLogId , context : string , message : string ) : void {
25+ this . log ( "notice" , id , context , message ) ;
26+ }
27+
28+ warning ( id : MongoLogId , context : string , message : string ) : void {
29+ this . log ( "warning" , id , context , message ) ;
30+ }
31+
32+ critical ( id : MongoLogId , context : string , message : string ) : void {
33+ this . log ( "critical" , id , context , message ) ;
34+ }
35+
36+ alert ( id : MongoLogId , context : string , message : string ) : void {
37+ this . log ( "alert" , id , context , message ) ;
38+ }
39+
40+ emergency ( id : MongoLogId , context : string , message : string ) : void {
41+ this . log ( "emergency" , id , context , message ) ;
42+ }
43+ }
44+
45+ class ConsoleLogger extends LoggerBase {
46+ log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void {
47+ message = redact ( message ) ;
48+ console . error ( `[${ level . toUpperCase ( ) } ] ${ id } - ${ context } : ${ message } ` ) ;
49+ }
50+ }
51+
52+ class Logger extends LoggerBase {
53+ constructor (
54+ private logWriter : MongoLogWriter ,
55+ private server : McpServer
56+ ) {
57+ super ( ) ;
58+ }
59+
60+ log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void {
61+ message = redact ( message ) ;
62+ const mongoDBLevel = this . mapToMongoDBLogLevel ( level ) ;
63+ this . logWriter [ mongoDBLevel ] ( "MONGODB-MCP" , id , context , message ) ;
64+ this . server . server . sendLoggingMessage ( {
65+ level,
66+ data : `[${ context } ]: ${ message } ` ,
67+ } ) ;
68+ }
69+
70+ private mapToMongoDBLogLevel ( level : LogLevel ) : "info" | "warn" | "error" | "debug" | "fatal" {
71+ switch ( level ) {
72+ case "info" :
73+ return "info" ;
74+ case "warning" :
75+ return "warn" ;
76+ case "error" :
77+ return "error" ;
78+ case "notice" :
79+ case "debug" :
80+ return "debug" ;
81+ case "critical" :
82+ case "alert" :
83+ case "emergency" :
84+ return "fatal" ;
85+ default :
86+ return "info" ;
87+ }
88+ }
89+ }
90+
91+ class ProxyingLogger extends LoggerBase {
92+ private internalLogger : LoggerBase = new ConsoleLogger ( ) ;
93+
94+ log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void {
95+ this . internalLogger . log ( level , id , context , message ) ;
96+ }
97+ }
98+
99+ const logger = new ProxyingLogger ( ) ;
100+ export default logger ;
101+
102+ export async function initializeLogger ( server : McpServer ) : Promise < void > {
10103 const logDir = path . join ( config . localDataPath , ".app-logs" ) ;
11104 await fs . mkdir ( logDir , { recursive : true } ) ;
12105
@@ -21,37 +114,6 @@ export async function initializeLogger(): Promise<void> {
21114
22115 await manager . cleanupOldLogFiles ( ) ;
23116
24- logWriter = await manager . createLogWriter ( ) ;
117+ const logWriter = await manager . createLogWriter ( ) ;
118+ logger [ "internalLogger" ] = new Logger ( logWriter , server ) ;
25119}
26-
27- const log = {
28- log ( level : "info" | "warn" | "error" | "debug" | "fatal" , id : MongoLogId , context : string , message : string ) : void {
29- message = redact ( message ) ;
30- if ( logWriter ) {
31- logWriter [ level ] ( "MONGODB-MCP" , id , context , message ) ;
32- } else {
33- console . error (
34- `[${ level . toUpperCase ( ) } ] Logger not initialized, dropping message: ${ message } , context: ${ context } , id: ${ id } `
35- ) ;
36- }
37- } ,
38-
39- info ( id : MongoLogId , context : string , message : string ) : void {
40- this . log ( "info" , id , context , message ) ;
41- } ,
42-
43- warn ( id : MongoLogId , context : string , message : string ) : void {
44- this . log ( "warn" , id , context , message ) ;
45- } ,
46- error ( id : MongoLogId , context : string , message : string ) : void {
47- this . log ( "error" , id , context , message ) ;
48- } ,
49- debug ( id : MongoLogId , context : string , message : string ) : void {
50- this . log ( "debug" , id , context , message ) ;
51- } ,
52- fatal ( id : MongoLogId , context : string , message : string ) : void {
53- this . log ( "fatal" , id , context , message ) ;
54- } ,
55- } ;
56-
57- export default log ;
0 commit comments