@@ -50,44 +50,95 @@ export const LogId = {
50
50
streamableHttpTransportCloseFailure : mongoLogId ( 1_006_006 ) ,
51
51
} as const ;
52
52
53
+ interface LogPayload {
54
+ id : MongoLogId ;
55
+ context : string ;
56
+ message : string ;
57
+ noRedaction ?: boolean | LoggerType | LoggerType [ ] ;
58
+ }
59
+
60
+ export type LoggerType = "console" | "disk" | "mcp" ;
61
+
53
62
export abstract class LoggerBase {
54
- abstract log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void ;
63
+ abstract log ( level : LogLevel , payload : Omit < LogPayload , "noRedaction" > ) : void ;
64
+
65
+ abstract type : LoggerType | null ;
66
+
67
+ private logCore ( level : LogLevel , payload : LogPayload ) {
68
+ // Default to not redacting mcp logs, redact everything else
69
+ const noRedaction = payload . noRedaction !== undefined ? payload . noRedaction : "mcp" ;
70
+
71
+ this . log ( level , {
72
+ id : payload . id ,
73
+ context : payload . context ,
74
+ message : this . redactIfNecessary ( payload . message , noRedaction ) ,
75
+ } ) ;
76
+ }
77
+
78
+ private redactIfNecessary ( message : string , noRedaction : LogPayload [ "noRedaction" ] ) : string {
79
+ if ( typeof noRedaction === "boolean" && noRedaction ) {
80
+ // If the consumer has supplied noRedaction: true, we don't redact the log message
81
+ // regardless of the logger type
82
+ return message ;
83
+ }
55
84
56
- info ( id : MongoLogId , context : string , message : string ) : void {
57
- this . log ( "info" , id , context , message ) ;
85
+ if ( typeof noRedaction === "string" && noRedaction === this . type ) {
86
+ // If the consumer has supplied noRedaction: logger-type, we skip redacting if
87
+ // our logger type is the same as what the consumer requested
88
+ return message ;
89
+ }
90
+
91
+ if (
92
+ typeof noRedaction === "object" &&
93
+ Array . isArray ( noRedaction ) &&
94
+ this . type !== null &&
95
+ noRedaction . indexOf ( this . type ) !== - 1
96
+ ) {
97
+ // If the consumer has supplied noRedaction: array, we skip redacting if our logger
98
+ // type is included in that array
99
+ return message ;
100
+ }
101
+
102
+ return redact ( message ) ;
103
+ }
104
+
105
+ info ( payload : LogPayload ) : void {
106
+ this . log ( "info" , payload ) ;
58
107
}
59
108
60
- error ( id : MongoLogId , context : string , message : string ) : void {
61
- this . log ( "error" , id , context , message ) ;
109
+ error ( payload : LogPayload ) : void {
110
+ this . log ( "error" , payload ) ;
62
111
}
63
- debug ( id : MongoLogId , context : string , message : string ) : void {
64
- this . log ( "debug" , id , context , message ) ;
112
+ debug ( payload : LogPayload ) : void {
113
+ this . log ( "debug" , payload ) ;
65
114
}
66
115
67
- notice ( id : MongoLogId , context : string , message : string ) : void {
68
- this . log ( "notice" , id , context , message ) ;
116
+ notice ( payload : LogPayload ) : void {
117
+ this . log ( "notice" , payload ) ;
69
118
}
70
119
71
- warning ( id : MongoLogId , context : string , message : string ) : void {
72
- this . log ( "warning" , id , context , message ) ;
120
+ warning ( payload : LogPayload ) : void {
121
+ this . log ( "warning" , payload ) ;
73
122
}
74
123
75
- critical ( id : MongoLogId , context : string , message : string ) : void {
76
- this . log ( "critical" , id , context , message ) ;
124
+ critical ( payload : LogPayload ) : void {
125
+ this . log ( "critical" , payload ) ;
77
126
}
78
127
79
- alert ( id : MongoLogId , context : string , message : string ) : void {
80
- this . log ( "alert" , id , context , message ) ;
128
+ alert ( payload : LogPayload ) : void {
129
+ this . log ( "alert" , payload ) ;
81
130
}
82
131
83
- emergency ( id : MongoLogId , context : string , message : string ) : void {
84
- this . log ( "emergency" , id , context , message ) ;
132
+ emergency ( payload : LogPayload ) : void {
133
+ this . log ( "emergency" , payload ) ;
85
134
}
86
135
}
87
136
88
137
export class ConsoleLogger extends LoggerBase {
89
- log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void {
90
- message = redact ( message ) ;
138
+ type : LoggerType = "console" ;
139
+
140
+ log ( level : LogLevel , payload : LogPayload ) : void {
141
+ const { id, context, message } = payload ;
91
142
console . error ( `[${ level . toUpperCase ( ) } ] ${ id . __value } - ${ context } : ${ message } (${ process . pid } )` ) ;
92
143
}
93
144
}
@@ -97,6 +148,8 @@ export class DiskLogger extends LoggerBase {
97
148
super ( ) ;
98
149
}
99
150
151
+ type : LoggerType = "disk" ;
152
+
100
153
static async fromPath ( logPath : string ) : Promise < DiskLogger > {
101
154
await fs . mkdir ( logPath , { recursive : true } ) ;
102
155
@@ -116,8 +169,8 @@ export class DiskLogger extends LoggerBase {
116
169
return new DiskLogger ( logWriter ) ;
117
170
}
118
171
119
- log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void {
120
- message = redact ( message ) ;
172
+ log ( level : LogLevel , payload : LogPayload ) : void {
173
+ const { id , context , message } = payload ;
121
174
const mongoDBLevel = this . mapToMongoDBLogLevel ( level ) ;
122
175
123
176
this . logWriter [ mongoDBLevel ] ( "MONGODB-MCP" , id , context , message ) ;
@@ -149,20 +202,24 @@ export class McpLogger extends LoggerBase {
149
202
super ( ) ;
150
203
}
151
204
152
- log ( level : LogLevel , _ : MongoLogId , context : string , message : string ) : void {
205
+ type : LoggerType = "mcp" ;
206
+
207
+ log ( level : LogLevel , payload : LogPayload ) : void {
153
208
// Only log if the server is connected
154
209
if ( ! this . server ?. isConnected ( ) ) {
155
210
return ;
156
211
}
157
212
158
213
void this . server . server . sendLoggingMessage ( {
159
214
level,
160
- data : `[${ context } ]: ${ message } ` ,
215
+ data : `[${ payload . context } ]: ${ payload . message } ` ,
161
216
} ) ;
162
217
}
163
218
}
164
219
165
220
class CompositeLogger extends LoggerBase {
221
+ type : LoggerType | null = null ;
222
+
166
223
private loggers : LoggerBase [ ] = [ ] ;
167
224
168
225
constructor ( ...loggers : LoggerBase [ ] ) {
@@ -178,9 +235,9 @@ class CompositeLogger extends LoggerBase {
178
235
this . loggers = [ ...loggers ] ;
179
236
}
180
237
181
- log ( level : LogLevel , id : MongoLogId , context : string , message : string ) : void {
238
+ log ( level : LogLevel , payload : LogPayload ) : void {
182
239
for ( const logger of this . loggers ) {
183
- logger . log ( level , id , context , message ) ;
240
+ logger . log ( level , payload ) ;
184
241
}
185
242
}
186
243
}
0 commit comments