@@ -140,7 +140,16 @@ export class Logger implements ILogger {
140
140
export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
141
141
private channel : LogOutputChannel ;
142
142
143
- constructor ( public channelName : string ) {
143
+ /**
144
+ * Creates an instance of the logging class.
145
+ *
146
+ * @param channelName - The name of the output channel.
147
+ * @param parser - A function that parses a log message and returns a tuple containing the parsed message and its log level, or undefined if the log should be filtered.
148
+ */
149
+ constructor (
150
+ channelName : string ,
151
+ private parser : ( message : string ) => [ string , LogLevel ] | undefined = LanguageClientOutputChannelAdapter . omnisharpLspParser . bind ( this )
152
+ ) {
144
153
this . channel = window . createOutputChannel ( channelName , { log : true } ) ;
145
154
}
146
155
@@ -149,41 +158,19 @@ export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
149
158
}
150
159
151
160
public append ( message : string ) : void {
152
- const [ parsedMessage , level ] = this . parse ( message ) ;
153
- this . sendLogMessage ( parsedMessage , level ) ;
161
+ const parseResult = this . parser ( message ) ;
162
+ if ( parseResult !== undefined ) { this . sendLogMessage ( ... parseResult ) ; }
154
163
}
155
164
156
- // We include the log level inline from PSES for VSCode because our LanguageClient doesn't support middleware for logMessages yet.
157
- // BUG:
158
- protected parse ( message : string ) : [ string , LogLevel ] {
159
- const logLevelMatch = / ^ < (?< level > T r a c e | D e b u g | I n f o | W a r n i n g | E r r o r ) > (?< message > .+ ) / . exec ( message ) ;
160
- if ( logLevelMatch ) {
161
- const { level, message } = logLevelMatch . groups ! ;
162
- let logLevel : LogLevel ;
163
- switch ( level ) {
164
- case "Trace" :
165
- logLevel = LogLevel . Trace ;
166
- break ;
167
- case "Debug" :
168
- logLevel = LogLevel . Debug ;
169
- break ;
170
- case "Info" :
171
- logLevel = LogLevel . Info ;
172
- break ;
173
- case "Warning" :
174
- logLevel = LogLevel . Warning ;
175
- break ;
176
- case "Error" :
177
- logLevel = LogLevel . Error ;
178
- break ;
179
- default :
180
- logLevel = LogLevel . Info ;
181
- break ;
182
- }
183
- return [ message , logLevel ] ;
184
- } else {
185
- return [ message , LogLevel . Info ] ;
186
- }
165
+ /** Converts from Omnisharp logs since middleware for LogMessage does not currently exist **/
166
+ public static omnisharpLspParser ( message : string ) : [ string , LogLevel ] {
167
+ const logLevelMatch = / ^ \[ (?< level > T r a c e | D e b u g | I n f o | W a r n | E r r o r ) + - \d + : \d + : \d + [ A P ] M \] (?< message > .+ ) / . exec ( message ) ;
168
+ const logLevel : LogLevel = logLevelMatch ?. groups ?. level
169
+ ? LogLevel [ logLevelMatch . groups . level as keyof typeof LogLevel ]
170
+ : LogLevel . Info ;
171
+ const logMessage = logLevelMatch ?. groups ?. message ?? message ;
172
+
173
+ return [ logMessage , logLevel ] ;
187
174
}
188
175
189
176
protected sendLogMessage ( message : string , level : LogLevel ) : void {
@@ -257,49 +244,40 @@ export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
257
244
// #endregion
258
245
}
259
246
260
- /** Appends additional */
261
- export class PsesMergedOutputChannel extends LanguageClientOutputChannelAdapter {
262
- public override appendLine ( message : string ) : void {
263
- this . append ( message ) ;
264
- }
265
-
266
- public override append ( message : string ) : void {
267
- const [ parsedMessage , level ] = this . parse ( message ) ;
268
-
269
- // Append PSES prefix to log messages to differentiate them from Client messages
270
- this . sendLogMessage ( "[PSES] " + parsedMessage , level ) ;
271
- }
247
+ /** Special parsing for PowerShell Editor Services LSP messages since the LogLevel cannot be read due to vscode
248
+ * LanguageClient Limitations (https://github.com/microsoft/vscode-languageserver-node/issues/1116)
249
+ */
250
+ export function PsesParser ( message : string ) : [ string , LogLevel ] {
251
+ const logLevelMatch = / ^ < (?< level > T r a c e | D e b u g | I n f o | W a r n i n g | E r r o r ) > (?< message > .+ ) / . exec ( message ) ;
252
+ const logLevel : LogLevel = logLevelMatch ?. groups ?. level
253
+ ? LogLevel [ logLevelMatch . groups . level as keyof typeof LogLevel ]
254
+ : LogLevel . Info ;
255
+ const logMessage = logLevelMatch ?. groups ?. message ?? message ;
256
+
257
+ return [ "[PSES] " + logMessage , logLevel ] ;
272
258
}
273
259
274
- /** Overrides the severity of some LSP traces to be more logical */
275
- export class LanguageClientTraceFormatter extends LanguageClientOutputChannelAdapter {
276
- public override appendLine ( message : string ) : void {
277
- this . append ( message ) ;
260
+ /** Lsp Trace Parser that does some additional parsing and formatting to make it look nicer */
261
+ export function LspTraceParser ( message : string ) : [ string , LogLevel ] {
262
+ let [ parsedMessage , level ] = LanguageClientOutputChannelAdapter . omnisharpLspParser ( message ) ;
263
+ if ( parsedMessage . startsWith ( "Sending " ) ) {
264
+ parsedMessage = parsedMessage . replace ( "Sending" , "➡️" ) ;
265
+ level = LogLevel . Debug ;
266
+ }
267
+ if ( parsedMessage . startsWith ( "Received " ) ) {
268
+ parsedMessage = parsedMessage . replace ( "Received" , "⬅️" ) ;
269
+ level = LogLevel . Debug ;
270
+ }
271
+ if ( parsedMessage . startsWith ( "Params:" )
272
+ || parsedMessage . startsWith ( "Result:" )
273
+ ) {
274
+ level = LogLevel . Trace ;
278
275
}
279
276
280
- public override append ( message : string ) : void {
281
- // eslint-disable-next-line prefer-const
282
- let [ parsedMessage , level ] = this . parse ( message ) ;
283
-
284
- if ( parsedMessage . startsWith ( "Sending " ) ) {
285
- parsedMessage = parsedMessage . replace ( "Sending" , "▶️" ) ;
286
- level = LogLevel . Debug ;
287
- }
288
- if ( parsedMessage . startsWith ( "Received " ) ) {
289
- parsedMessage = parsedMessage . replace ( "Received" , "◀️" ) ;
290
- level = LogLevel . Debug ;
291
- }
292
- if ( parsedMessage . startsWith ( "Params:" )
293
- || parsedMessage . startsWith ( "Result:" )
294
- ) {
295
- level = LogLevel . Trace ;
296
- }
297
-
298
- // These are PSES messages we don't really need to see so we drop these to trace
299
- if ( parsedMessage . startsWith ( "◀️ notification 'window/logMessage'" ) ) {
300
- level = LogLevel . Trace ;
301
- }
302
-
303
- this . sendLogMessage ( parsedMessage . trimEnd ( ) , level ) ;
277
+ // These are PSES messages we don't really need to see so we drop these to trace
278
+ if ( parsedMessage . startsWith ( "⬅️ notification 'window/logMessage'" ) ) {
279
+ level = LogLevel . Trace ;
304
280
}
281
+
282
+ return [ parsedMessage . trimEnd ( ) , level ] ;
305
283
}
0 commit comments