1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
3
4
+ using System ;
4
5
using System . IO ;
5
6
using System . Linq ;
6
7
using System . Threading . Tasks ;
7
8
using Microsoft . Extensions . DependencyInjection ;
8
9
using Microsoft . Extensions . Logging ;
9
10
using Microsoft . PowerShell . EditorServices . Handlers ;
10
11
using Microsoft . PowerShell . EditorServices . Hosting ;
12
+ using Microsoft . PowerShell . EditorServices . Logging ;
11
13
using Microsoft . PowerShell . EditorServices . Services ;
12
14
using Microsoft . PowerShell . EditorServices . Services . Extension ;
13
15
using Microsoft . PowerShell . EditorServices . Services . PowerShell . Host ;
14
16
using Newtonsoft . Json . Linq ;
15
17
using OmniSharp . Extensions . JsonRpc ;
18
+ using OmniSharp . Extensions . LanguageServer . Protocol . General ;
16
19
using OmniSharp . Extensions . LanguageServer . Protocol . Server ;
17
20
using OmniSharp . Extensions . LanguageServer . Server ;
18
21
@@ -26,14 +29,15 @@ namespace Microsoft.PowerShell.EditorServices.Server
26
29
/// </summary>
27
30
internal class PsesLanguageServer
28
31
{
29
- internal HostLogger LoggerFactory { get ; }
32
+ internal HostLogger HostLogger { get ; }
30
33
internal ILanguageServer LanguageServer { get ; private set ; }
31
34
private readonly LogLevel _minimumLogLevel ;
32
35
private readonly Stream _inputStream ;
33
36
private readonly Stream _outputStream ;
34
37
private readonly HostStartupInfo _hostDetails ;
35
38
private readonly TaskCompletionSource < bool > _serverStart ;
36
39
private PsesInternalHost _psesHost ;
40
+ private IDisposable hostLoggerSubscription ;
37
41
38
42
/// <summary>
39
43
/// Create a new language server instance.
@@ -43,18 +47,18 @@ internal class PsesLanguageServer
43
47
/// cref="EditorServicesServerFactory.CreateLanguageServer"/>. It is essentially a
44
48
/// singleton. The factory hides the logger.
45
49
/// </remarks>
46
- /// <param name="factory">Factory to create loggers with .</param>
50
+ /// <param name="hostLogger">The host logger to hand off for monitoring .</param>
47
51
/// <param name="inputStream">Protocol transport input stream.</param>
48
52
/// <param name="outputStream">Protocol transport output stream.</param>
49
53
/// <param name="hostStartupInfo">Host configuration to instantiate the server and services
50
54
/// with.</param>
51
55
public PsesLanguageServer (
52
- HostLogger factory ,
56
+ HostLogger hostLogger ,
53
57
Stream inputStream ,
54
58
Stream outputStream ,
55
59
HostStartupInfo hostStartupInfo )
56
60
{
57
- LoggerFactory = factory ;
61
+ HostLogger = hostLogger ;
58
62
_minimumLogLevel = ( LogLevel ) hostStartupInfo . LogLevel ;
59
63
_inputStream = inputStream ;
60
64
_outputStream = outputStream ;
@@ -86,9 +90,7 @@ public async Task StartAsync()
86
90
. ConfigureLogging ( builder => builder
87
91
. ClearProviders ( )
88
92
. AddLanguageProtocolLogging ( )
89
- // TODO: AddHostLogger which registers the host logger provider above as a LoggingProvider (MEL version of a "sink")
90
93
. SetMinimumLevel ( _minimumLogLevel ) )
91
- // TODO: Consider replacing all WithHandler with AddSingleton
92
94
. WithHandler < PsesWorkspaceSymbolsHandler > ( )
93
95
. WithHandler < PsesTextDocumentHandler > ( )
94
96
. WithHandler < GetVersionHandler > ( )
@@ -127,6 +129,11 @@ public async Task StartAsync()
127
129
. OnInitialize (
128
130
( languageServer , initializeParams , cancellationToken ) =>
129
131
{
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
+
130
137
// Set the workspace path from the parameters.
131
138
WorkspaceService workspaceService = languageServer . Services . GetService < WorkspaceService > ( ) ;
132
139
if ( initializeParams . WorkspaceFolders is not null )
@@ -161,7 +168,9 @@ public async Task StartAsync()
161
168
162
169
_psesHost = languageServer . Services . GetService < PsesInternalHost > ( ) ;
163
170
return _psesHost . TryStartAsync ( hostStartOptions , cancellationToken ) ;
164
- } ) ;
171
+ }
172
+ )
173
+ . OnShutdown ( _ => hostLoggerSubscription . Dispose ( ) ) ;
165
174
} ) . ConfigureAwait ( false ) ;
166
175
167
176
_serverStart . SetResult ( true ) ;
0 commit comments