Skip to content
Massimo Bonvicini edited this page Aug 27, 2019 · 3 revisions

Description

Configuration

The following section describe how to configure the Logging module.

  • Level
  • Format
  • Targets
  • CustomTargets

Level

The Level property defines the default logging level. Valid values are:

* NOTSET    ( 0)
* DEBUG     (10)
* INFO      (20)
* WARNING   (30)
* ERROR     (40)

For example:

> Get-LoggingDefaultLevel                       # Get the default value
NOTSET                                          # NOTSET level
> Set-LoggingDefaultLevel -Level 'ERROR'        # Set default level to ERROR
> Get-LoggingDefaultLevel                       # Get the current global level
ERROR

Format

The Format property defines how the message is rendered.

The default value is: [%{timestamp}] [%{level:-7}] %{message}

The Log object has a number of attributes that are replaced in the format string to produce the message:

Format Description
%{timestamp} Time when the log message was created. Defaults to %Y-%m-%d %T%Z (2016-04-20 14:22:45+02). Take a look at this Technet article about the UFormat parameter, and this Technet article for available [DateTimeFormatInfo]
%{timestamputc} UTC Time when the log message was created. Defaults to %Y-%m-%d %T%Z (2016-04-20 12:22:45+02). Take a look at this Technet article about the UFormat parameter, and this Technet article for available [DateTimeFormatInfo]
%{level} Text logging level for the message (DEBUG, INFO, WARNING, ERROR)
%{levelno} Number logging level for the message (10, 20, 30, 40)
%{lineno} The line number on wich the write occured
%{pathname} The path of the caller
%{filename} The file name part of the caller
%{caller} The caller function name
%{message} The logged message
%{body} The logged body (json format not pretty printed)
%{execinfo} The ErrorRecord catched in a try/catch statement
%{pid} The process id of the currently running powershellprocess ($PID)

After the placeholder name you can pass a padding or a date format string separated by a colon (:):

Note: A format string starting with a percent symbol (%) will use the UFormat parameter of Get-Date

Padding

If the padding value is negative, the field will be left aligned and padded with spaces on the right:

> Set-LoggingDefaultFormat -Format '[%{level:-7}]'
[DEBUG  ]
[INFO   ]
[WARNING]
[ERROR  ]

If the padding value is positive, the field will be right aligned and padded with spaces on the left:

> Set-LoggingDefaultFormat -Format '[%{level:7}]'
[  DEBUG]
[   INFO]
[WARNING]
[  ERROR]

Date format string

The date format string starts with a plus sign (+) followed by UFormat OR Format ([DateTimeFormatInfo]) parameters. See here for available UFormats, and here for available Formats.

> Set-LoggingDefaultFormat -Format '%{timestamp}'
2016-04-20 13:31:12+02

> Set-LoggingDefaultFormat -Format '%{timestamp:+%A, %B %d, %Y}'
Wednesday, April 20, 2016

> Set-LoggingDefaultFormat -Format '[%{timestamp:+%T:12}]'   # You could also use padding and date format string at the same time
[   13:31:12]

> Set-LoggingDefaultFormat -Format '[%{timestamp:+yyyy/MM/dd HH:mm:ss.fff}]'
[2016/04/20 13:31:12.431]

Caller

By default the caller cmdlet is assumed to be the parent function in the executing stack, i.e., the function directly calling the Write-Log cmdlet. However, there are instances where a wrapper cmdlet is used on top of Write-Log to trigger the logging, thus invalidating the default assumption for the caller.

In these scenarios, it is possible to set the caller scope using Set-LoggingCallerScope, which is shown in the example below along with the usage of a wrapper logging cmdlet.

# Write-CustomLog is the wrapper logging cmdlet
# If the default caller scope is used, it would print 'Write-CustomLog' everytime
# filename has value only if the code below is executed in a script

Add-LoggingTarget -Name Console -Configuration @{Level = 'DEBUG'; Format = '[%{filename}] [%{caller}] %{message}'}
Set-LoggingCallerScope 2

function Write-CustomLog {
    [CmdletBinding()]
    param(
        $Level,
        $Message
    )

    Write-Log -Level $Level -Message $Message
}

function Invoke-CallerFunctionWithCustomLog {
    1..5 | ForEach-Object {
        # In this example, during execution of Write-Log the numeric scope represents the following:
        # 0 - Write-Log scope
        # 1 - Write-CustomLog scope (which would be default value)
        # 2 - Invoke-CallerFunctionWithCustomLog
        Write-CustomLog -Level (Get-Random 'DEBUG', 'INFO', 'WARNING', 'ERROR') -Message 'Hello, World! (With caller scope at level 2)'
    }
}

Invoke-CallerFunctionWithCustomLog

Contributing

Please use issues system or GitHub pull requests to contribute to the project.

For more information, see CONTRIBUTING

Notes

  • The dispatcher thread starts on module import and keeps running in the background to dispatch new messages until the module is removed.
  • The runspace code is inspired by the work and research of Boe Prox (@proxb).