PowerShell module implementing logging to the console and/or text files using StreamWriter.
Most (if not all) available PowerShell logging modules are not designed for efficiency. They may have many nice features, but when it comes to logging to text files, they all make calls that work like this:
- Open text file.
- Read the file to the end.
- Write message to the file.
- Close the file.
This may not be a big deal, but as your log file grows, your script performance will have to pay a performance penalty. If you are not willing to tolerate performance degradation caused by the logging calls, consider using this module.
As the name implies, the StreamLogging
module uses the standard .NET StreamWriter class to implement logging. Instead of opening and closing the file every time the script needs to write a message, it keeps the stream open until logging is complete.
You can define the log configuration settings using the Start-Logging
function. The function initializes log settings using the explicitly specified parameter or an optional configuration file (function parameters always take precedence). The default configuration file must be located in the same folder as the calling script and named after it with the .StreamLogging.json
extension (you can adjust the extension or specify the whole path via the ConfigFile
parameter). A sample configuration file is included. You can also check a working sample at the PowerShell script template repository.
The StreamLogging
module can write to the console and/or a text file. It can also copy errors to a dedicated error file. You can define the log targets using the -Console
, -File
, and -ErrorFile
switches. (The switches and parameters identified in the Configuration section are applied once during log initialization.)
Console is the default log target (you do not need to use the Console
switch unless you set the file switches). When writing to the console, the module uses different colors to identify message log levels. You can force the console output to use the same colors via the ForegroundColor
and BackgroundColor
parameters (you can also reassign different colors to the log levels via the configuration file).
The default log and error files are created in the same folder as the running script and have the same name and .log
and .err.log
extensions). You can specify your own log and error file paths or customize the parts of the default file paths using the Format-LogFilePath
method. By default, before a new log file gets created, an old log file (with the same name) will be backed up (with a timestamp appended to the file name). You can also append new log entries to the existing files or simply overwrite them using the Append
or Overwrite
switches.
StreamLogging
supports the following log levels:
None
: Logging is turned off.Error
: Only errors and exceptions are logged.Warning
: Warnings and errors are logged.Info
: Informational messsages are logged along with warnings and errors.Debug
: Debug messages are logged along with everything else.
When logging entries to the files, you can include timestamps and/or log levels via the WithTimestamp
and/or WithLogLevel
switches. By default, timestamps will reflect local time, but you can also use Universal time if you set the UtcTime
switch.
Once you initialize the log settings, you can start writing log entries to the specified targets: console and/or files. Normally, you would log string messages (assigned log levels), but you can also log error information from the global $Error
object (default) or your custom exception (you will need to pass it explicitly).
You can indent a log entry by setting the Indent
parameter to a positive number identifying the number of tabs (tab size is configurable).
When writing log entries, you can force the module to skip writing to the console or files even if they are set ups as logging targets using the NoConsole
and NoFile
switches.
You can download a copy of the module from this Github repository or install it from the PowerShell Gallery.
The StreamLogging
module exposes the following functions:
Allows you to customize parts of the default log or error file paths. The default log file are created in the same folder as the calling script with the same name and the .log
and .err.log
extensions. For example, for the script path C:\Scripts\MyScript.ps1
, the default log and error file paths would be C:\Scripts\MyScript.log
and C:\Scripts\MyScript.err.log
respectively. Say, you want to use the default names and extensions but place the file in the D:\Logs
folder. This is how you generate the file paths:
$logFilePath = Format-LogFilePath -Directory "D:\Logs" # -> D:\Logs\MyScript.log
$errFilePath = Format-LogFilePath -Directory "D:\Logs" -IsErrorFile # -> D:\Logs\MyScript.err.log
Returns logging configuration settings (in case you want to verify or print them). Notice that the returned configuration does not reflect console font and background colors assigned to different log levels. By default, logging configuration settings are returned in the form of a hash table, but you can use the Json
and/or the Compress
switches to return them in the JSON or compressed JSON format:
$logConfig = Get-LoggingConfig
$logConfigJson = Get-LoggingConfig -Json
$logConfigJson = Get-LoggingConfig -Compress
Initializes log settings (but does not create the log or error files until the first entry is written). By default, the initialization function will configure logging to write informational messages, warnings, and errors the console. You can adjust the setting by passing them to the Start-Logging
function explicitly, or define them in the configuration file (command-line parameters have higher precedence than the configuration file values). The configuration file is not required but you may find it handy.
If you do not specify the configuration file, the module will look for the default file; otherwise, it will try to use the ConfigFile
parameter value as a file path and, if it does not find one, it will append the value to the script name and try it one more time (see the Configuration section).
Here are a few examples of log initialization calls:
Start-Logging
Initializes default log settings or use whatever settings are configured in the default configuration file if one exists.
Start-Logging -ConfigFile ".Log.config"
Initializes log settings using the custom configuration file with path formatted by appending .Log.config
to the path of the running script.
Start-Logging -ConfigFile "D:\Common\LogConfig.json"
Initializes log settings using the custom configuration file with the D:\Common\LogConfig.json
path.
Start-Logging -ConfigFile "D:\Common\LogConfig.json" -LogLevel Debug -WithLogLevel -WithTimestamp -UtcTime
Initializes log settings using the custom configuration file with the D:\Common\LogConfig.json
path, but sets the log level to Debug
, and add prefix with the UTC timestamp and message log level to each line written to the log and/or error files.
Closes open files and resets log settings. If you are logging to files, make sure you call this function before your script exits:
Stop-Logging
Writes a log entry of the specified log level (Info
is the default) to the log targets. You can also use it to log an error object. Hera are a few examples of how you can invoke the Write-Log
function:
"Hello, info!" | Write-Log
Write-Log "Hello, info!"
Write-Log "Hello, debug" -LogLevel Debug -Indent 1
Write-Log -Error -NoConsole -Raw
Write-Log -Error "Hello, error"
Write-Log -LogLevel Warning "Hello, warning"
Write-Log -LogLevel Debug "Hello, debug!" -NoFile
Write-Log -LogLevel Debug "My object:" -Object ({"Key1":"Value1";"Key2":"Value2"}) -Compress
Writes a debug message to the log targets, e.g.:
"Hello, debug!" | Write-LogDebug
Write-LogDebug "Hello, debug!" -Indent 1
Write-LogDebug -Message "Hello, debug!" -NoFile
Write-LogDebug "My object:" -Object ({"Key1":"Value1";"Key2":"Value2"}) -Compress
Writes an error message to the log targets, e.g.:
"Hello, error!" | Write-LogError
Write-LogError "Hello, error!" -Indent 1
Write-LogError -Message "Hello, error!" -NoFile
Write-LogError "My object:" -Object ({"Key1":"Value1";"Key2":"Value2"}) -Compress
Writes error information from the global $Error
object or a custom exception to the log targets:
Write-LogException
Write-LogException Raw
Write-LogException $Error
$Error | Write-Exception -Raw
Writes an informational message to the log targets, e.g.:
"Hello, info!" | Write-LogInfo
Write-LogInfo "Hello, info!" -Indent 1
Write-LogInfo -Message "Hello, info!" -NoFile
Write-LogInfo "My object:" -Object ({"Key1":"Value1";"Key2":"Value2"}) -Compress
Writes a warning to the log targets, e.g.:
"Hello, warning!" | Write-LogWarning
Write-LogWarning "Hello, warning!" -Indent 1
Write-LogWarning -Message "Hello, warning!" -NoFile
Write-LogWarning "My object:" -Object ({"Key1":"Value1";"Key2":"Value2"}) -Compress
For a more complete example illustrating how to use the StreamLogging
module, see the sample script.