Skip to content

Commit e766e07

Browse files
committed
Wire up HostLogger
1 parent b9bd92e commit e766e07

File tree

3 files changed

+19
-18
lines changed

3 files changed

+19
-18
lines changed

src/PowerShellEditorServices.Hosting/Commands/StartEditorServicesCommand.cs

-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ protected override void BeginProcessing()
219219
protected override void EndProcessing()
220220
{
221221
_logger.Log(PsesLogLevel.Diagnostic, "Beginning EndProcessing block");
222-
223222
try
224223
{
225224
// First try to remove PSReadLine to decomplicate startup

src/PowerShellEditorServices/Logging/HostLoggerAdapter.cs

+3-10
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,16 @@ namespace Microsoft.PowerShell.EditorServices.Logging
99
/// <summary>
1010
/// Adapter class to allow logging events sent by the host to be recorded by PSES' logging infrastructure.
1111
/// </summary>
12-
internal class HostLoggerAdapter : IObserver<(int logLevel, string message)>
12+
internal class HostLoggerAdapter(ILogger logger) : IObserver<(int logLevel, string message)>
1313
{
14-
private readonly ILogger _logger;
14+
public void OnError(Exception error) => logger.LogError(error, "Error in host logger");
1515

16-
/// <summary>
17-
/// Create a new host logger adapter.
18-
/// </summary>
19-
/// <param name="loggerFactory">Factory to create logger instances with.</param>
20-
public HostLoggerAdapter(ILoggerFactory loggerFactory) => _logger = loggerFactory.CreateLogger("HostLogs");
16+
public void OnNext((int logLevel, string message) value) => logger.Log((LogLevel)value.logLevel, value.message);
2117

2218
public void OnCompleted()
2319
{
2420
// Nothing to do; we simply don't send more log messages
2521
}
2622

27-
public void OnError(Exception error) => _logger.LogError(error, "Error in host logger");
28-
29-
public void OnNext((int logLevel, string message) value) => _logger.Log((LogLevel)value.logLevel, value.message);
3023
}
3124
}

src/PowerShellEditorServices/Server/PsesLanguageServer.cs

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
using System;
45
using System.IO;
56
using System.Linq;
67
using System.Threading.Tasks;
78
using Microsoft.Extensions.DependencyInjection;
89
using Microsoft.Extensions.Logging;
910
using Microsoft.PowerShell.EditorServices.Handlers;
1011
using Microsoft.PowerShell.EditorServices.Hosting;
12+
using Microsoft.PowerShell.EditorServices.Logging;
1113
using Microsoft.PowerShell.EditorServices.Services;
1214
using Microsoft.PowerShell.EditorServices.Services.Extension;
1315
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host;
1416
using Newtonsoft.Json.Linq;
1517
using OmniSharp.Extensions.JsonRpc;
18+
using OmniSharp.Extensions.LanguageServer.Protocol.General;
1619
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
1720
using OmniSharp.Extensions.LanguageServer.Server;
1821

@@ -26,14 +29,15 @@ namespace Microsoft.PowerShell.EditorServices.Server
2629
/// </summary>
2730
internal class PsesLanguageServer
2831
{
29-
internal HostLogger LoggerFactory { get; }
32+
internal HostLogger HostLogger { get; }
3033
internal ILanguageServer LanguageServer { get; private set; }
3134
private readonly LogLevel _minimumLogLevel;
3235
private readonly Stream _inputStream;
3336
private readonly Stream _outputStream;
3437
private readonly HostStartupInfo _hostDetails;
3538
private readonly TaskCompletionSource<bool> _serverStart;
3639
private PsesInternalHost _psesHost;
40+
private IDisposable hostLoggerSubscription;
3741

3842
/// <summary>
3943
/// Create a new language server instance.
@@ -43,18 +47,18 @@ internal class PsesLanguageServer
4347
/// cref="EditorServicesServerFactory.CreateLanguageServer"/>. It is essentially a
4448
/// singleton. The factory hides the logger.
4549
/// </remarks>
46-
/// <param name="factory">Factory to create loggers with.</param>
50+
/// <param name="hostLogger">The host logger to hand off for monitoring.</param>
4751
/// <param name="inputStream">Protocol transport input stream.</param>
4852
/// <param name="outputStream">Protocol transport output stream.</param>
4953
/// <param name="hostStartupInfo">Host configuration to instantiate the server and services
5054
/// with.</param>
5155
public PsesLanguageServer(
52-
HostLogger factory,
56+
HostLogger hostLogger,
5357
Stream inputStream,
5458
Stream outputStream,
5559
HostStartupInfo hostStartupInfo)
5660
{
57-
LoggerFactory = factory;
61+
HostLogger = hostLogger;
5862
_minimumLogLevel = (LogLevel)hostStartupInfo.LogLevel;
5963
_inputStream = inputStream;
6064
_outputStream = outputStream;
@@ -86,9 +90,7 @@ public async Task StartAsync()
8690
.ConfigureLogging(builder => builder
8791
.ClearProviders()
8892
.AddLanguageProtocolLogging()
89-
// TODO: AddHostLogger which registers the host logger provider above as a LoggingProvider (MEL version of a "sink")
9093
.SetMinimumLevel(_minimumLogLevel))
91-
// TODO: Consider replacing all WithHandler with AddSingleton
9294
.WithHandler<PsesWorkspaceSymbolsHandler>()
9395
.WithHandler<PsesTextDocumentHandler>()
9496
.WithHandler<GetVersionHandler>()
@@ -127,6 +129,11 @@ public async Task StartAsync()
127129
.OnInitialize(
128130
(languageServer, initializeParams, cancellationToken) =>
129131
{
132+
// Wire up the HostLogger to the LanguageServer's logger once we are initialized, so that any messages still logged to the HostLogger get sent across the LSP channel. There is no more logging to disk at this point.
133+
hostLoggerSubscription = HostLogger.Subscribe(new HostLoggerAdapter(
134+
languageServer.Services.GetService<ILogger<HostLogger>>()
135+
));
136+
130137
// Set the workspace path from the parameters.
131138
WorkspaceService workspaceService = languageServer.Services.GetService<WorkspaceService>();
132139
if (initializeParams.WorkspaceFolders is not null)
@@ -161,7 +168,9 @@ public async Task StartAsync()
161168

162169
_psesHost = languageServer.Services.GetService<PsesInternalHost>();
163170
return _psesHost.TryStartAsync(hostStartOptions, cancellationToken);
164-
});
171+
}
172+
)
173+
.OnShutdown(_ => hostLoggerSubscription.Dispose());
165174
}).ConfigureAwait(false);
166175

167176
_serverStart.SetResult(true);

0 commit comments

Comments
 (0)