|
12 | 12 | namespace Microsoft.PowerShell.EditorServices.Hosting
|
13 | 13 | {
|
14 | 14 | /// <summary>
|
15 |
| -/// User-facing log level for editor services configuration. |
| 15 | +/// Log Level for HostLogger. This is a direct copy of LogLevel from Microsoft.Extensions.Logging, and will map to |
| 16 | +/// MEL.LogLevel once MEL is bootstrapped, but we don't want to load any MEL assemblies until the Assembly Load |
| 17 | +/// Context is set up. |
16 | 18 | /// </summary>
|
17 |
| -/// <remarks> |
18 |
| -/// The underlying values of this enum attempt to align to |
19 |
| -/// <see cref="Microsoft.Extensions.Logging.LogLevel" /> |
20 |
| -/// </remarks> |
21 | 19 | public enum PsesLogLevel
|
22 | 20 | {
|
23 |
| -Diagnostic = 0, |
24 |
| -Verbose = 1, |
25 |
| -Normal = 2, |
| 21 | +/// <summary> |
| 22 | +/// Logs that contain the most detailed messages. These messages may contain sensitive application data. |
| 23 | +/// These messages are disabled by default and should never be enabled in a production environment. |
| 24 | +/// </summary> |
| 25 | +Trace = 0, |
| 26 | + |
| 27 | +/// <summary> |
| 28 | +/// Logs that are used for interactive investigation during development. These logs should primarily contain |
| 29 | +/// information useful for debugging and have no long-term value. |
| 30 | +/// </summary> |
| 31 | +Debug = 1, |
| 32 | + |
| 33 | +/// <summary> |
| 34 | +/// Logs that track the general flow of the application. These logs should have long-term value. |
| 35 | +/// </summary> |
| 36 | +Information = 2, |
| 37 | + |
| 38 | +/// <summary> |
| 39 | +/// Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the |
| 40 | +/// application execution to stop. |
| 41 | +/// </summary> |
26 | 42 | Warning = 3,
|
| 43 | + |
| 44 | +/// <summary> |
| 45 | +/// Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a |
| 46 | +/// failure in the current activity, not an application-wide failure. |
| 47 | +/// </summary> |
27 | 48 | Error = 4,
|
28 |
| -None = 5 |
| 49 | + |
| 50 | +/// <summary> |
| 51 | +/// Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires |
| 52 | +/// immediate attention. |
| 53 | +/// </summary> |
| 54 | +Critical = 5, |
| 55 | + |
| 56 | +/// <summary> |
| 57 | +/// Not used for writing log messages. Specifies that a logging category should not write any messages. |
| 58 | +/// </summary> |
| 59 | +None = 6, |
29 | 60 | }
|
30 | 61 |
|
31 | 62 | /// <summary>
|
@@ -180,15 +211,9 @@ public void LogException(
|
180 | 211 | /// Since it's likely that the process will end when PSES shuts down,
|
181 | 212 | /// there's no good reason to need objects rather than writing directly to the host.
|
182 | 213 | /// </remarks>
|
183 |
| -internal class PSHostLogger : IObserver<(PsesLogLevel logLevel, string message)> |
| 214 | +/// <param name="ui">The PowerShell host user interface object to log output to.</param> |
| 215 | +internal class PSHostLogger(PSHostUserInterface ui) : IObserver<(PsesLogLevel logLevel, string message)> |
184 | 216 | {
|
185 |
| -private readonly PSHostUserInterface _ui; |
186 |
| - |
187 |
| -/// <summary> |
188 |
| -/// Create a new PowerShell host logger. |
189 |
| -/// </summary> |
190 |
| -/// <param name="ui">The PowerShell host user interface object to log output to.</param> |
191 |
| -public PSHostLogger(PSHostUserInterface ui) => _ui = ui; |
192 | 217 |
|
193 | 218 | public void OnCompleted()
|
194 | 219 | {
|
@@ -200,35 +225,37 @@ public void OnCompleted()
|
200 | 225 |
|
201 | 226 | public void OnNext((PsesLogLevel logLevel, string message) value)
|
202 | 227 | {
|
203 |
| -switch (value.logLevel) |
| 228 | +(PsesLogLevel logLevel, string message) = value; |
| 229 | +switch (logLevel) |
204 | 230 | {
|
205 |
| -case PsesLogLevel.Diagnostic: |
206 |
| -_ui.WriteDebugLine(value.message); |
207 |
| -return; |
208 |
| - |
209 |
| -case PsesLogLevel.Verbose: |
210 |
| -_ui.WriteVerboseLine(value.message); |
211 |
| -return; |
| 231 | +case PsesLogLevel.Trace: |
| 232 | +case PsesLogLevel.Debug: |
| 233 | +ui.WriteDebugLine(message); |
| 234 | +break; |
212 | 235 |
|
213 |
| -case PsesLogLevel.Normal: |
214 |
| -_ui.WriteLine(value.message); |
215 |
| -return; |
| 236 | +case PsesLogLevel.Information: |
| 237 | +ui.WriteVerboseLine(message); |
| 238 | +break; |
216 | 239 |
|
217 | 240 | case PsesLogLevel.Warning:
|
218 |
| -_ui.WriteWarningLine(value.message); |
219 |
| -return; |
| 241 | +ui.WriteWarningLine(message); |
| 242 | +break; |
220 | 243 |
|
221 | 244 | case PsesLogLevel.Error:
|
222 |
| -_ui.WriteErrorLine(value.message); |
223 |
| -return; |
| 245 | +case PsesLogLevel.Critical: |
| 246 | +ui.WriteErrorLine(message); |
| 247 | +break; |
224 | 248 |
|
225 | 249 | default:
|
226 |
| -_ui.WriteLine(value.message); |
227 |
| -return; |
| 250 | +ui.WriteLine(message); |
| 251 | +break; |
228 | 252 | }
|
229 | 253 | }
|
230 | 254 | }
|
231 | 255 |
|
| 256 | +/// <summary> |
| 257 | +/// A simple log sink that logs to a stream, typically used to log to a file. |
| 258 | +/// </summary> |
232 | 259 | internal class StreamLogger : IObserver<(PsesLogLevel logLevel, string message)>, IDisposable
|
233 | 260 | {
|
234 | 261 | public static StreamLogger CreateWithNewFile(string path)
|
@@ -283,9 +310,7 @@ public void OnCompleted()
|
283 | 310 | }
|
284 | 311 |
|
285 | 312 | _cancellationSource.Cancel();
|
286 |
| - |
287 | 313 | _writerThread.Join();
|
288 |
| - |
289 | 314 | _unsubscriber.Dispose();
|
290 | 315 | _fileWriter.Flush();
|
291 | 316 | _fileWriter.Close();
|
@@ -298,29 +323,17 @@ public void OnCompleted()
|
298 | 323 |
|
299 | 324 | public void OnNext((PsesLogLevel logLevel, string message) value)
|
300 | 325 | {
|
301 |
| -string message = null; |
302 |
| -switch (value.logLevel) |
| 326 | +string message = value.logLevel switch |
303 | 327 | {
|
304 |
| -case PsesLogLevel.Diagnostic: |
305 |
| -message = $"[DBG]: {value.message}"; |
306 |
| -break; |
307 |
| - |
308 |
| -case PsesLogLevel.Verbose: |
309 |
| -message = $"[VRB]: {value.message}"; |
310 |
| -break; |
311 |
| - |
312 |
| -case PsesLogLevel.Normal: |
313 |
| -message = $"[INF]: {value.message}"; |
314 |
| -break; |
315 |
| - |
316 |
| -case PsesLogLevel.Warning: |
317 |
| -message = $"[WRN]: {value.message}"; |
318 |
| -break; |
319 |
| - |
320 |
| -case PsesLogLevel.Error: |
321 |
| -message = $"[ERR]: {value.message}"; |
322 |
| -break; |
323 |
| -} |
| 328 | +// String interpolation often considered a logging sin is OK here because our filtering happens before. |
| 329 | +PsesLogLevel.Trace => $"[TRC]: {value.message}", |
| 330 | +PsesLogLevel.Debug => $"[DBG]: {value.message}", |
| 331 | +PsesLogLevel.Information => $"[INF]: {value.message}", |
| 332 | +PsesLogLevel.Warning => $"[WRN]: {value.message}", |
| 333 | +PsesLogLevel.Error => $"[ERR]: {value.message}", |
| 334 | +PsesLogLevel.Critical => $"[CRT]: {value.message}", |
| 335 | +_ => value.message, |
| 336 | +}; |
324 | 337 |
|
325 | 338 | _messageQueue.Add(message);
|
326 | 339 | }
|
|
0 commit comments