Skip to content

Commit 434a49d

Browse files
Upgrade the LSP client library for better logging support (#8281)
2 parents 8e8eacc + 6d28b76 commit 434a49d

File tree

9 files changed

+80
-114
lines changed

9 files changed

+80
-114
lines changed

.vscode/tasks.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"group": {
1616
"kind": "build",
1717
"isDefault": true
18-
}
18+
},
19+
"problemMatcher": "$tsc",
1920
},
2021
{
2122
"label": "buildDev",
@@ -25,7 +26,8 @@
2526
"group": {
2627
"kind": "build",
2728
"isDefault": true
28-
}
29+
},
30+
"problemMatcher": "$tsc",
2931
},
3032
{
3133
"label": "package",
@@ -35,7 +37,8 @@
3537
"group": {
3638
"kind": "build",
3739
"isDefault": true
38-
}
40+
},
41+
"problemMatcher": "$tsc",
3942
},
4043
{
4144
"label": "packageDev",
@@ -45,7 +48,8 @@
4548
"group": {
4649
"kind": "build",
4750
"isDefault": true
48-
}
51+
},
52+
"problemMatcher": "$tsc",
4953
},
5054
{
5155
"label": "test",

package-lock.json

Lines changed: 27 additions & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@
119119
"tmp": "0.0.33",
120120
"uuid": "^9.0.0",
121121
"vscode-html-languageservice": "^5.3.1",
122-
"vscode-jsonrpc": "9.0.0-next.7",
123-
"vscode-languageclient": "10.0.0-next.14",
124-
"vscode-languageserver-protocol": "3.17.6-next.12",
122+
"vscode-jsonrpc": "9.0.0-next.8",
123+
"vscode-languageclient": "10.0.0-next.15",
124+
"vscode-languageserver-protocol": "3.17.6-next.13",
125125
"vscode-languageserver-textdocument": "1.0.12",
126126
"vscode-languageserver-types": "3.17.6-next.6",
127127
"vscode-nls": "5.0.1",

src/lsptoolshost/activate.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { registerRazorEndpoints } from './razor/razorEndpoints';
3434
import { registerTraceCommand } from './profiling/profiling';
3535

3636
let _channel: vscode.LogOutputChannel;
37-
let _traceChannel: vscode.OutputChannel;
37+
let _traceChannel: vscode.LogOutputChannel;
3838

3939
/**
4040
* Creates and activates the Roslyn language server.
@@ -52,8 +52,7 @@ export async function activateRoslynLanguageServer(
5252
// Create a channel for outputting general logs from the language server.
5353
_channel = outputChannel;
5454
// Create a separate channel for outputting trace logs - these are incredibly verbose and make other logs very difficult to see.
55-
// The trace channel verbosity is controlled by the _channel verbosity.
56-
_traceChannel = vscode.window.createOutputChannel(vscode.l10n.t('C# LSP Trace Logs'));
55+
_traceChannel = vscode.window.createOutputChannel(vscode.l10n.t('C# LSP Trace Logs'), { log: true });
5756

5857
reporter.sendTelemetryEvent(TelemetryEventNames.ClientInitialize);
5958

src/lsptoolshost/server/roslynLanguageServer.ts

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,10 @@ export class RoslynLanguageServer {
127127
private _context: vscode.ExtensionContext,
128128
private _telemetryReporter: TelemetryReporter,
129129
private _languageServerEvents: RoslynLanguageServerEvents,
130-
private _channel: vscode.LogOutputChannel
130+
private _channel: vscode.LogOutputChannel,
131+
private _traceChannel: vscode.LogOutputChannel
131132
) {
132-
this.registerSetTrace();
133+
this.registerOutputChannelsChangeHandlers();
133134
this.registerSendOpenSolution();
134135
this.registerProjectInitialization();
135136
this.registerServerStateChanged();
@@ -164,29 +165,41 @@ export class RoslynLanguageServer {
164165
return RoslynLanguageServer._processId;
165166
}
166167

167-
private registerSetTrace() {
168-
// Set the language client trace level based on the log level option.
169-
// setTrace only works after the client is already running.
168+
private registerOutputChannelsChangeHandlers() {
170169
this._languageClient.onDidChangeState(async (state) => {
171170
if (state.newState === State.Running) {
172-
await this.updateLogLevel();
171+
await this.updateOutputChannelLogLevel();
172+
await this.updateTraceChannelLogLevel();
173173
}
174174
});
175175
// Register for changes to the log level.
176176
this._channel.onDidChangeLogLevel(async () => {
177-
await this.updateLogLevel();
177+
await this.updateOutputChannelLogLevel();
178+
});
179+
this._traceChannel.onDidChangeLogLevel(async () => {
180+
// The LSP client also responds to didChangeLogLevel and sets its own logic; we want to override that so do a small delay
181+
setTimeout(async () => {
182+
await this.updateTraceChannelLogLevel();
183+
}, 1);
178184
});
179185
}
180186

181-
private async updateLogLevel(): Promise<void> {
187+
private async updateOutputChannelLogLevel(): Promise<void> {
182188
if (this._languageClient.state === State.Running) {
183-
const languageClientTraceLevel = RoslynLanguageServer.GetTraceLevel(this._channel.logLevel);
184189
// Update the server's log level.
185190
await this.sendNotification('roslyn/updateLogLevel', {
186191
logLevel: RoslynLanguageServer.GetServerLogLevel(this._channel.logLevel),
187192
});
188-
// Update the trace level that the client uses to log trace messages.
189-
await this._languageClient.setTrace(languageClientTraceLevel);
193+
}
194+
}
195+
196+
private async updateTraceChannelLogLevel(): Promise<void> {
197+
if (this._languageClient.state === State.Running) {
198+
await this._languageClient.setTrace(
199+
// If the logLevel is set to trace, we want to have verbose tracing. All tracing from the LSP client is done at 'trace' level,
200+
// so we can't show tracing at any other output window levels, since it just gets filtered away.
201+
this._traceChannel.logLevel == vscode.LogLevel.Trace ? Trace.Verbose : Trace.Off
202+
);
190203
}
191204
}
192205

@@ -266,7 +279,7 @@ export class RoslynLanguageServer {
266279
additionalExtensionPaths: string[],
267280
languageServerEvents: RoslynLanguageServerEvents,
268281
channel: vscode.LogOutputChannel,
269-
traceChannel: vscode.OutputChannel
282+
traceChannel: vscode.LogOutputChannel
270283
): Promise<RoslynLanguageServer> {
271284
const devKit = getCSharpDevKit();
272285
if (devKit) {
@@ -329,7 +342,8 @@ export class RoslynLanguageServer {
329342
context,
330343
telemetryReporter,
331344
languageServerEvents,
332-
channel
345+
channel,
346+
traceChannel
333347
);
334348

335349
client.registerFeature(server._onAutoInsertFeature);
@@ -1102,25 +1116,6 @@ export class RoslynLanguageServer {
11021116
}
11031117
}
11041118

1105-
private static GetTraceLevel(logLevel: vscode.LogLevel): Trace {
1106-
switch (logLevel) {
1107-
case vscode.LogLevel.Trace:
1108-
return Trace.Verbose;
1109-
case vscode.LogLevel.Debug:
1110-
return Trace.Messages;
1111-
case vscode.LogLevel.Info:
1112-
return Trace.Off;
1113-
case vscode.LogLevel.Warning:
1114-
return Trace.Off;
1115-
case vscode.LogLevel.Error:
1116-
return Trace.Off;
1117-
case vscode.LogLevel.Off:
1118-
return Trace.Off;
1119-
default:
1120-
throw new Error(`Invalid log level ${logLevel}`);
1121-
}
1122-
}
1123-
11241119
public async getBuildOnlyDiagnosticIds(token: vscode.CancellationToken): Promise<string[]> {
11251120
// If the server isn't running, no build diagnostics to get
11261121
if (!this.isRunning()) {

src/omnisharp/engines/lspEngine.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import * as ObservableEvents from '../omnisharpLoggingEvents';
1313
import { EventStream } from '../../eventStream';
1414
import CompositeDisposable from '../../compositeDisposable';
1515
import Disposable from '../../disposable';
16-
import { ExtensionContext, CancellationTokenSource, OutputChannel, Location, CodeLens, Uri } from 'vscode';
16+
import { ExtensionContext, CancellationTokenSource, LogOutputChannel, Location, CodeLens, Uri } from 'vscode';
1717
import { LanguageMiddlewareFeature } from '../languageMiddlewareFeature';
1818
import { Events, OmniSharpServer } from '../server';
1919
import { IEngine } from './IEngine';
@@ -42,7 +42,7 @@ export class LspEngine implements IEngine {
4242
private eventBus: EventEmitter,
4343
private eventStream: EventStream,
4444
private context: ExtensionContext,
45-
private outputChannel: OutputChannel,
45+
private outputChannel: LogOutputChannel,
4646
private disposables: CompositeDisposable,
4747
private languageMiddlewareFeature: LanguageMiddlewareFeature,
4848
private platformInfo: PlatformInformation,

src/omnisharp/omnisharpLanguageServer.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,13 @@ export async function activateOmniSharpLanguageServer(
8989
eventStream.subscribe(dotnetTestChannelObserver.post);
9090
eventStream.subscribe(dotnetTestLoggerObserver.post);
9191

92-
const omnisharpChannel = vscode.window.createOutputChannel(vscode.l10n.t('OmniSharp Log'));
92+
// If we're in LSP mode, we can create a LogOutputChannel since that's what the LSP client now supports.
93+
// If we're not in LSP mode, we'll create a regular OutputChannel since the log formatting expects to be able to write
94+
// it's own formatted outputs which gets mixed up with LogOutputChannels.s
95+
const omnisharpChannel = omnisharpOptions.enableLspDriver
96+
? vscode.window.createOutputChannel(vscode.l10n.t('OmniSharp Log'), { log: true })
97+
: vscode.window.createOutputChannel(vscode.l10n.t('OmniSharp Log'));
98+
9399
const omnisharpLogObserver = new OmnisharpLoggerObserver(omnisharpChannel, platformInfo);
94100
const omnisharpChannelObserver = new OmnisharpChannelObserver(omnisharpChannel);
95101
eventStream.subscribe(omnisharpLogObserver.post);

src/omnisharp/server.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { Subject } from 'rxjs';
2121
import { debounceTime } from 'rxjs/operators';
2222
import CompositeDisposable from '../compositeDisposable';
2323
import Disposable from '../disposable';
24-
import { ExtensionContext, OutputChannel } from 'vscode';
24+
import { ExtensionContext, LogOutputChannel, OutputChannel } from 'vscode';
2525
import { LanguageMiddlewareFeature } from './languageMiddlewareFeature';
2626
import { LspEngine } from './engines/lspEngine';
2727
import { IEngine } from './engines/IEngine';
@@ -314,7 +314,8 @@ export class OmniSharpServer {
314314
this._eventBus,
315315
this.eventStream,
316316
this.context,
317-
this.outputChannel,
317+
// If we are in LSP mode, then we created an LogOutputChannel originally
318+
this.outputChannel as LogOutputChannel,
318319
disposables,
319320
this.languageMiddlewareFeature,
320321
this.platformInfo,

src/razor/src/razorLanguageServerOptions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as vscode from 'vscode';
77

88
export interface RazorLanguageServerOptions {
99
serverPath: string;
10-
outputChannel?: vscode.OutputChannel;
10+
outputChannel?: vscode.LogOutputChannel;
1111
debug?: boolean;
1212
usingOmniSharp: boolean;
1313
suppressErrorToasts: boolean;

0 commit comments

Comments
 (0)