11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4+ using System ;
45using System . IO ;
56using System . Linq ;
67using System . Threading . Tasks ;
78using Microsoft . Extensions . DependencyInjection ;
89using Microsoft . Extensions . Logging ;
910using Microsoft . PowerShell . EditorServices . Handlers ;
1011using Microsoft . PowerShell . EditorServices . Hosting ;
12+ using Microsoft . PowerShell . EditorServices . Logging ;
1113using Microsoft . PowerShell . EditorServices . Services ;
1214using Microsoft . PowerShell . EditorServices . Services . Extension ;
1315using Microsoft . PowerShell . EditorServices . Services . PowerShell . Host ;
1416using Newtonsoft . Json . Linq ;
1517using OmniSharp . Extensions . JsonRpc ;
18+ using OmniSharp . Extensions . LanguageServer . Protocol . General ;
1619using OmniSharp . Extensions . LanguageServer . Protocol . Server ;
1720using 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