From 5681d734d9e9908b9ad50b7a1520b2788d6dc0ba Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 20 Nov 2018 11:07:56 -0800 Subject: [PATCH 01/10] Optimize array creation --- src/PowerShellEditorServices/Workspace/Workspace.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index ce0df719e..e96526152 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -22,6 +22,13 @@ public class Workspace { #region Private Fields + private static readonly string[] s_psFilePatterns = new [] + { + "*.ps1", + "*.psm1", + "*.psd1" + }; + private ILogger logger; private Version powerShellVersion; private Dictionary workspaceFiles = new Dictionary(); @@ -295,7 +302,6 @@ public IEnumerable EnumeratePSFiles() private IEnumerable RecursivelyEnumerateFiles(string folderPath) { var foundFiles = Enumerable.Empty(); - var patterns = new string[] { @"*.ps1", @"*.psm1", @"*.psd1" }; try { @@ -326,7 +332,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) e); } - foreach (var pattern in patterns) + foreach (var pattern in s_psFilePatterns) { try { From 4a4615312c160a144c1722012f9c39ebea832acf Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 20 Nov 2018 11:42:07 -0800 Subject: [PATCH 02/10] Recurse directories manually with a stack --- .../Workspace/Workspace.cs | 112 ++++++++++++------ 1 file changed, 76 insertions(+), 36 deletions(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index e96526152..f5ab83cde 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -299,66 +299,106 @@ public IEnumerable EnumeratePSFiles() #region Private Methods + /// + /// Find PowerShell files recursively down from a given directory path. + /// Currently returns files in depth-first order. + /// Directory.GetFiles(folderPath, pattern, SearchOption.AllDirectories) would provide this, + /// but a cycle in the filesystem will cause that to enter an infinite loop. + /// + /// The absolute path of the base folder to search. + /// + /// All PowerShell files in the recursive directory hierarchy under the given base directory, up to 64 directories deep. + /// private IEnumerable RecursivelyEnumerateFiles(string folderPath) { - var foundFiles = Enumerable.Empty(); + var foundFiles = new List(); + var dirStack = new Stack(); - try + // Kick the search off with the base directory + dirStack.Push(folderPath); + + const int recursionDepthLimit = 64; + while (dirStack.Any()) { - IEnumerable subDirs = Directory.GetDirectories(folderPath); - foreach (string dir in subDirs) + string currDir = dirStack.Pop(); + + // Look for any PowerShell files in the current directory + foreach (string pattern in s_psFilePatterns) { - foundFiles = - foundFiles.Concat( - RecursivelyEnumerateFiles(dir)); + string[] psFiles; + try + { + psFiles = Directory.GetFiles(currDir, pattern, SearchOption.TopDirectoryOnly); + } + catch (DirectoryNotFoundException e) + { + this.logger.WriteException( + $"Could not enumerate files in the path '{currDir}' due to it being an invalid path", + e); + + continue; + } + catch (PathTooLongException e) + { + this.logger.WriteException( + $"Could not enumerate files in the path '{currDir}' due to the path being too long", + e); + + continue; + } + catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) + { + this.logger.WriteException( + $"Could not enumerate files in the path '{currDir}' due to the path not being accessible", + e); + + continue; + } + + foundFiles.AddRange(psFiles); } - } - catch (DirectoryNotFoundException e) - { - this.logger.WriteException( - $"Could not enumerate files in the path '{folderPath}' due to it being an invalid path", - e); - } - catch (PathTooLongException e) - { - this.logger.WriteException( - $"Could not enumerate files in the path '{folderPath}' due to the path being too long", - e); - } - catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) - { - this.logger.WriteException( - $"Could not enumerate files in the path '{folderPath}' due to the path not being accessible", - e); - } - foreach (var pattern in s_psFilePatterns) - { + // Prevent unbounded recursion here + // If we get too deep, keep processing but go no deeper + if (dirStack.Count >= recursionDepthLimit) + { + continue; + } + + // Add the recursive directories to search next + string[] subDirs; try { - foundFiles = - foundFiles.Concat( - Directory.GetFiles( - folderPath, - pattern)); + subDirs = Directory.GetFiles(currDir, pattern, SearchOption.TopDirectoryOnly); } catch (DirectoryNotFoundException e) { this.logger.WriteException( - $"Could not enumerate files in the path '{folderPath}' due to a path being an invalid path", + $"Could not enumerate directories in the path '{currDir}' due to it being an invalid path", e); + + continue; } catch (PathTooLongException e) { this.logger.WriteException( - $"Could not enumerate files in the path '{folderPath}' due to a path being too long", + $"Could not enumerate directories in the path '{currDir}' due to the path being too long", e); + + continue; } catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) { this.logger.WriteException( - $"Could not enumerate files in the path '{folderPath}' due to a path not being accessible", + $"Could not enumerate directories in the path '{currDir}' due to the path not being accessible", e); + + continue; + } + + foreach (string subDir in subDirs) + { + dirStack.Push(subDir); } } From c4dcb9afe6a6aca1367bf31aa5515294e083422c Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 20 Nov 2018 11:47:13 -0800 Subject: [PATCH 03/10] Add handled exception logging as warning --- .../Utility/PsesLogger.cs | 21 ++++++++++++++++++- .../Workspace/Workspace.cs | 12 +++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/PowerShellEditorServices/Utility/PsesLogger.cs b/src/PowerShellEditorServices/Utility/PsesLogger.cs index b7ad8f6b2..8edb3d3b5 100644 --- a/src/PowerShellEditorServices/Utility/PsesLogger.cs +++ b/src/PowerShellEditorServices/Utility/PsesLogger.cs @@ -16,6 +16,11 @@ public class PsesLogger : ILogger /// private static readonly string ErrorLevelName = LogLevel.Error.ToString().ToUpper(); + /// + /// The name of the WARNING log level. + /// + private static readonly string WarningLevelName = LogLevel.Warning.ToString().ToUpper(); + /// /// The internal Serilog logger to log to. /// @@ -57,7 +62,7 @@ public void Write( int threadId = Thread.CurrentThread.ManagedThreadId; - string messageTemplate = + string messageTemplate = "[{LogLevelName:l}] tid:{threadId} in '{CallerName:l}' {CallerSourceFile:l}:{CallerLineNumber}:{IndentedLogMsg:l}"; switch (logLevel) @@ -101,6 +106,20 @@ public void WriteException( ErrorLevelName, callerSourceFile, callerName, callerLineNumber, errorMessage, indentedException); } + public void WriteHandledException( + string errorMessage, + Exception exception, + [CallerMemberName] string callerName = null, + [CallerFilePath] string callerSourceFile = null, + [CallerLineNumber] int callerLineNumber = 0) + { + string indentedException = IndentMsg(exception.ToString()); + + _logger.Warning("[{WarningLevelName:l}] {CallerSourceFile:l}: In method '{CallerName:l}', line {CallerLineNumber}: Handled exception {ErrorMessage:l}{IndentedException:l}", + WarningLevelName, callerSourceFile, callerName, callerLineNumber, errorMessage, indentedException); + } + + /// /// Utility function to indent a log message by one level. /// diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index f5ab83cde..b92ec3023 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -332,7 +332,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) } catch (DirectoryNotFoundException e) { - this.logger.WriteException( + this.logger.WriteHandledException( $"Could not enumerate files in the path '{currDir}' due to it being an invalid path", e); @@ -340,7 +340,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) } catch (PathTooLongException e) { - this.logger.WriteException( + this.logger.WriteHandledException( $"Could not enumerate files in the path '{currDir}' due to the path being too long", e); @@ -348,7 +348,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) } catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) { - this.logger.WriteException( + this.logger.WriteHandledException( $"Could not enumerate files in the path '{currDir}' due to the path not being accessible", e); @@ -373,7 +373,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) } catch (DirectoryNotFoundException e) { - this.logger.WriteException( + this.logger.WriteHandledException( $"Could not enumerate directories in the path '{currDir}' due to it being an invalid path", e); @@ -381,7 +381,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) } catch (PathTooLongException e) { - this.logger.WriteException( + this.logger.WriteHandledException( $"Could not enumerate directories in the path '{currDir}' due to the path being too long", e); @@ -389,7 +389,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) } catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) { - this.logger.WriteException( + this.logger.WriteHandledException( $"Could not enumerate directories in the path '{currDir}' due to the path not being accessible", e); From dc4dd7a99b568970d3f8929d50bb06e143caf9ec Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 20 Nov 2018 11:49:52 -0800 Subject: [PATCH 04/10] Add handled exception logging to ILogger --- .../BuildInfo/BuildInfo.cs | 6 +++--- src/PowerShellEditorServices/Utility/Logging.cs | 15 +++++++++++++++ .../Utility/PsesLogger.cs | 8 ++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs b/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs index 181a42589..9cb2037dc 100644 --- a/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs +++ b/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs @@ -2,8 +2,8 @@ namespace Microsoft.PowerShell.EditorServices.Host { public static class BuildInfo { - public const string BuildVersion = ""; - public const string BuildOrigin = ""; - public static readonly System.DateTime? BuildTime = null; + public const string BuildVersion = ""; + public const string BuildOrigin = ""; + public static readonly System.DateTime? BuildTime = System.DateTime.Parse("2018-11-20T11:49:16"); } } diff --git a/src/PowerShellEditorServices/Utility/Logging.cs b/src/PowerShellEditorServices/Utility/Logging.cs index f4320eb59..6813feacb 100644 --- a/src/PowerShellEditorServices/Utility/Logging.cs +++ b/src/PowerShellEditorServices/Utility/Logging.cs @@ -78,6 +78,21 @@ void WriteException( [CallerMemberName] string callerName = null, [CallerFilePath] string callerSourceFile = null, [CallerLineNumber] int callerLineNumber = 0); + + /// + /// Log an exception that has been handled cleanly or is otherwise not expected to cause problems in the logs. + /// + /// The error message of the exception to be logged. + /// The exception itself that has been thrown. + /// The name of the method in which the ILogger is being called. + /// The name of the source file in which the ILogger is being called. + /// The line number in the file where the ILogger is being called. + void WriteHandledException( + string errorMessage, + Exception exception, + [CallerMemberName] string callerName = null, + [CallerFilePath] string callerSourceFile = null, + [CallerLineNumber] int callerLineNumber = 0); } diff --git a/src/PowerShellEditorServices/Utility/PsesLogger.cs b/src/PowerShellEditorServices/Utility/PsesLogger.cs index 8edb3d3b5..12a7af9b4 100644 --- a/src/PowerShellEditorServices/Utility/PsesLogger.cs +++ b/src/PowerShellEditorServices/Utility/PsesLogger.cs @@ -106,6 +106,14 @@ public void WriteException( ErrorLevelName, callerSourceFile, callerName, callerLineNumber, errorMessage, indentedException); } + /// + /// Log an exception that has been handled cleanly or is otherwise not expected to cause problems in the logs. + /// + /// The error message of the exception to be logged. + /// The exception itself that has been thrown. + /// The name of the method in which the ILogger is being called. + /// The name of the source file in which the ILogger is being called. + /// The line number in the file where the ILogger is being called. public void WriteHandledException( string errorMessage, Exception exception, From b12eba46b7b42965974ab31dc60ff827120e478d Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 20 Nov 2018 11:50:36 -0800 Subject: [PATCH 05/10] Fix Directory.GetDirectories usage --- src/PowerShellEditorServices/Workspace/Workspace.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index b92ec3023..7bb1a893c 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -369,7 +369,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) string[] subDirs; try { - subDirs = Directory.GetFiles(currDir, pattern, SearchOption.TopDirectoryOnly); + subDirs = Directory.GetDirectories(currDir); } catch (DirectoryNotFoundException e) { From 00e484829cdf903e0dfe6fd00f2d5276c03be3b4 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 20 Nov 2018 11:53:34 -0800 Subject: [PATCH 06/10] Revert change to buildinfo file --- src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs b/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs index 9cb2037dc..181a42589 100644 --- a/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs +++ b/src/PowerShellEditorServices.Host/BuildInfo/BuildInfo.cs @@ -2,8 +2,8 @@ namespace Microsoft.PowerShell.EditorServices.Host { public static class BuildInfo { - public const string BuildVersion = ""; - public const string BuildOrigin = ""; - public static readonly System.DateTime? BuildTime = System.DateTime.Parse("2018-11-20T11:49:16"); + public const string BuildVersion = ""; + public const string BuildOrigin = ""; + public static readonly System.DateTime? BuildTime = null; } } From 13222c06f62d9748b4af78ad202cb403c6b0d3d2 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Nov 2018 21:21:27 -0800 Subject: [PATCH 07/10] Add standard log template --- .../Utility/PsesLogger.cs | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/PowerShellEditorServices/Utility/PsesLogger.cs b/src/PowerShellEditorServices/Utility/PsesLogger.cs index 12a7af9b4..d5a48fa49 100644 --- a/src/PowerShellEditorServices/Utility/PsesLogger.cs +++ b/src/PowerShellEditorServices/Utility/PsesLogger.cs @@ -11,6 +11,12 @@ namespace Microsoft.PowerShell.EditorServices.Utility /// public class PsesLogger : ILogger { + /// + /// The standard log template for all log entries. + /// + private static readonly string s_logMessageTemplate = + "[{LogLevelName:l}] tid:{ThreadId} in '{CallerName:l}' {CallerSourceFile:l} (line {CallerLineNumber}):{IndentedLogMsg:l}"; + /// /// The name of the ERROR log level. /// @@ -62,25 +68,22 @@ public void Write( int threadId = Thread.CurrentThread.ManagedThreadId; - string messageTemplate = - "[{LogLevelName:l}] tid:{threadId} in '{CallerName:l}' {CallerSourceFile:l}:{CallerLineNumber}:{IndentedLogMsg:l}"; - switch (logLevel) { case LogLevel.Diagnostic: - _logger.Verbose(messageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); + _logger.Verbose(s_logMessageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); return; case LogLevel.Verbose: - _logger.Debug(messageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); + _logger.Debug(s_logMessageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); return; case LogLevel.Normal: - _logger.Information(messageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); + _logger.Information(s_logMessageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); return; case LogLevel.Warning: - _logger.Warning(messageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); + _logger.Warning(s_logMessageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); return; case LogLevel.Error: - _logger.Error(messageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); + _logger.Error(s_logMessageTemplate, logLevelName, threadId, callerName, callerSourceFile, callerLineNumber, indentedLogMsg); return; } } @@ -100,10 +103,8 @@ public void WriteException( [CallerFilePath] string callerSourceFile = null, [CallerLineNumber] int callerLineNumber = 0) { - string indentedException = IndentMsg(exception.ToString()); - - _logger.Error("[{ErrorLevelName:l}] {CallerSourceFile:l}: In method '{CallerName:l}', line {CallerLineNumber}: {ErrorMessage:l}{IndentedException:l}", - ErrorLevelName, callerSourceFile, callerName, callerLineNumber, errorMessage, indentedException); + string body = IndentExceptionMessage("Exception", errorMessage, exception); + Write(LogLevel.Error, body, callerName, callerSourceFile, callerLineNumber); } /// @@ -121,13 +122,10 @@ public void WriteHandledException( [CallerFilePath] string callerSourceFile = null, [CallerLineNumber] int callerLineNumber = 0) { - string indentedException = IndentMsg(exception.ToString()); - - _logger.Warning("[{WarningLevelName:l}] {CallerSourceFile:l}: In method '{CallerName:l}', line {CallerLineNumber}: Handled exception {ErrorMessage:l}{IndentedException:l}", - WarningLevelName, callerSourceFile, callerName, callerLineNumber, errorMessage, indentedException); + string body = IndentExceptionMessage("Handled exception", errorMessage, exception); + Write(LogLevel.Warning, body, callerName, callerSourceFile, callerLineNumber); } - /// /// Utility function to indent a log message by one level. /// @@ -135,13 +133,36 @@ public void WriteHandledException( /// The indented log message string. private static string IndentMsg(string logMessage) { - return new StringBuilder(logMessage) + return IndentMsg(new StringBuilder(logMessage)); + } + + /// + /// Utility function to indent a log message by one level. + /// + /// Log message string builder to transform. + /// The indented log message string. + private static string IndentMsg(StringBuilder logMessageBuilder) + { + return logMessageBuilder .Replace(Environment.NewLine, s_indentedPrefix) .Insert(0, s_indentedPrefix) .AppendLine() .ToString(); } + private static string IndentExceptionMessage( + string messagePrelude, + string errorMessage, + Exception exception) + { + var sb = new StringBuilder() + .Append(messagePrelude).Append(": ").Append(errorMessage).Append(Environment.NewLine) + .Append(Environment.NewLine) + .Append(exception.ToString()); + + return IndentMsg(sb); + } + /// /// A newline followed by a single indentation prefix. /// From 72d2a5b71577234d52231340b42742bac73c3082 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 26 Nov 2018 21:24:35 -0800 Subject: [PATCH 08/10] Add doc comments for new method --- src/PowerShellEditorServices/Utility/PsesLogger.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/PowerShellEditorServices/Utility/PsesLogger.cs b/src/PowerShellEditorServices/Utility/PsesLogger.cs index d5a48fa49..caf3ceca5 100644 --- a/src/PowerShellEditorServices/Utility/PsesLogger.cs +++ b/src/PowerShellEditorServices/Utility/PsesLogger.cs @@ -150,6 +150,13 @@ private static string IndentMsg(StringBuilder logMessageBuilder) .ToString(); } + /// + /// Creates a prettified log message from an exception. + /// + /// The user-readable tag for this exception entry. + /// The user-readable short description of the error. + /// The exception object itself. Must not be null. + /// An indented, formatted string of the body. private static string IndentExceptionMessage( string messagePrelude, string errorMessage, From 91ed4a3dda3a5fd84de0ab162993d80c0ca34108 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 27 Nov 2018 12:52:13 -0800 Subject: [PATCH 09/10] Add recursion limit logging --- src/PowerShellEditorServices/Workspace/Workspace.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PowerShellEditorServices/Workspace/Workspace.cs b/src/PowerShellEditorServices/Workspace/Workspace.cs index 7bb1a893c..7dc328b41 100644 --- a/src/PowerShellEditorServices/Workspace/Workspace.cs +++ b/src/PowerShellEditorServices/Workspace/Workspace.cs @@ -362,6 +362,7 @@ private IEnumerable RecursivelyEnumerateFiles(string folderPath) // If we get too deep, keep processing but go no deeper if (dirStack.Count >= recursionDepthLimit) { + this.logger.Write(LogLevel.Warning, $"Recursion depth limit hit for path {folderPath}"); continue; } From d4e737a0ef8d706419f89ae714e0addde95239bb Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 27 Nov 2018 12:59:48 -0800 Subject: [PATCH 10/10] Fix usage of indentation logic --- .../Utility/PsesLogger.cs | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/PowerShellEditorServices/Utility/PsesLogger.cs b/src/PowerShellEditorServices/Utility/PsesLogger.cs index caf3ceca5..b60ea603b 100644 --- a/src/PowerShellEditorServices/Utility/PsesLogger.cs +++ b/src/PowerShellEditorServices/Utility/PsesLogger.cs @@ -62,6 +62,24 @@ public void Write( [CallerMemberName] string callerName = null, [CallerFilePath] string callerSourceFile = null, [CallerLineNumber] int callerLineNumber = 0) + { + Write(logLevel, new StringBuilder(logMessage), callerName, callerSourceFile, callerLineNumber); + } + + /// + /// Write a message with the given severity to the logs. Takes a StringBuilder to allow for minimal allocation. + /// + /// The severity level of the log message. + /// The log message itself in StringBuilder form for manipulation. + /// The name of the calling method. + /// The name of the source file of the caller. + /// The line number where the log is being called. + private void Write( + LogLevel logLevel, + StringBuilder logMessage, + [CallerMemberName] string callerName = null, + [CallerFilePath] string callerSourceFile = null, + [CallerLineNumber] int callerLineNumber = 0) { string indentedLogMsg = IndentMsg(logMessage); string logLevelName = logLevel.ToString().ToUpper(); @@ -103,7 +121,7 @@ public void WriteException( [CallerFilePath] string callerSourceFile = null, [CallerLineNumber] int callerLineNumber = 0) { - string body = IndentExceptionMessage("Exception", errorMessage, exception); + StringBuilder body = FormatExceptionMessage("Exception", errorMessage, exception); Write(LogLevel.Error, body, callerName, callerSourceFile, callerLineNumber); } @@ -122,20 +140,10 @@ public void WriteHandledException( [CallerFilePath] string callerSourceFile = null, [CallerLineNumber] int callerLineNumber = 0) { - string body = IndentExceptionMessage("Handled exception", errorMessage, exception); + StringBuilder body = FormatExceptionMessage("Handled exception", errorMessage, exception); Write(LogLevel.Warning, body, callerName, callerSourceFile, callerLineNumber); } - /// - /// Utility function to indent a log message by one level. - /// - /// The log message to indent. - /// The indented log message string. - private static string IndentMsg(string logMessage) - { - return IndentMsg(new StringBuilder(logMessage)); - } - /// /// Utility function to indent a log message by one level. /// @@ -157,7 +165,7 @@ private static string IndentMsg(StringBuilder logMessageBuilder) /// The user-readable short description of the error. /// The exception object itself. Must not be null. /// An indented, formatted string of the body. - private static string IndentExceptionMessage( + private static StringBuilder FormatExceptionMessage( string messagePrelude, string errorMessage, Exception exception) @@ -167,7 +175,7 @@ private static string IndentExceptionMessage( .Append(Environment.NewLine) .Append(exception.ToString()); - return IndentMsg(sb); + return sb; } ///