@@ -140,7 +140,16 @@ export class Logger implements ILogger {
140140export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
141141 private channel : LogOutputChannel ;
142142
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+ ) {
144153 this . channel = window . createOutputChannel ( channelName , { log : true } ) ;
145154 }
146155
@@ -149,41 +158,19 @@ export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
149158 }
150159
151160 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 ) ; }
154163 }
155164
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 ] ;
187174 }
188175
189176 protected sendLogMessage ( message : string , level : LogLevel ) : void {
@@ -257,49 +244,40 @@ export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
257244 // #endregion
258245}
259246
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 ] ;
272258}
273259
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 ;
278275 }
279276
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 ;
304280 }
281+
282+ return [ parsedMessage . trimEnd ( ) , level ] ;
305283}
0 commit comments