Noveris.Logger.psm1
<#
#> $script:LoggerTypes = @{} $script:LoggerDefault = $null $ErrorActionPreference = "Stop" Class LoggerType { [string]$Name [string]$Prefix [Nullable[System.ConsoleColor]]$Color [string]$LogPath [bool]$WriteHost [bool]$WriteOutput [ScriptBlock]$FormatBlock [ScriptBlock]$OutputBlock LoggerType([string]$Name) { $this.Name = $Name $this.Prefix = [string]::Empty $this.Color = $null $this.LogPath = [string]::Empty $this.WriteHost = $false $this.WriteOutput = $false $this.FormatBlock = $null $this.OutputBlock = $null } LoggerType([LoggerType] $loggerType) { $this.Name = $loggerType.Name $this.Prefix = $loggerType.Prefix $this.Color = $loggerType.Color $this.LogPath = $loggerType.LogPath $this.WriteHost = $loggerType.WriteHost $this.WriteOutput = $loggerType.WriteOutput $this.FormatBlock = $loggerType.FormatBlock $this.OutputBlock = $loggerType.OutputBlock } } <# .SYNOPSIS Generate a new Logger Type for use by Write-Logger when generating messages. Names are accepted by pipeline or parameter. .PARAMETER Name The name of the Logger Type .PARAMETER Prefix A string value to prefix the message with. This is performed after any FormatBlock script. .PARAMETER Color The Color to use when writing content via Write-Host. .PARAMETER LogPath Path to a file to write finalised message content to. Contents are appended and written in UTF8 format. .PARAMETER WriteHost Determine whether the message should be written to the console using Write-Host .PARAMETER WriteOutput Determine whether the message should be written as object output from the function .PARAMETER FormatBlock Script Block to be called for reformat the original message e.g. { "test: $_" } .PARAMETER OutputBlock Script Block to be called with the finalised message text. .PARAMETER Default Defines whether this Logger Type should be the default logger type #> Function New-LoggerType { [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0,ValueFromPipeline)] [string]$Name, [Parameter(Mandatory=$false)] [string]$Prefix = [string]::Empty, [Parameter(Mandatory=$false)] [Nullable[System.ConsoleColor]]$Color = $null, [Parameter(Mandatory=$false)] [string]$LogPath = [string]::Empty, [Parameter(Mandatory=$false)] [switch]$WriteHost = $false, [Parameter(Mandatory=$false)] [switch]$WriteOutput = $false, [Parameter(Mandatory=$false)] [ScriptBlock]$FormatBlock = $null, [Parameter(Mandatory=$false)] [ScriptBlock]$OutputBlock = $null, [Parameter(Mandatory=$false)] [switch]$Default = $false ) process { if ([string]::IsNullOrEmpty($Name)) { throw New-Object ArgumentException -ArgumentList "Name supplied to New-Logger is null or empty" } if ($script:LoggerTypes.ContainsKey($Name)) { throw New-Object ArgumentException -ArgumentList "Name supplied to New-Logger already exists" } Write-Verbose "Creating new logger type: ${Name}" $newType = New-Object LoggerType -ArgumentList $Name $newType.WriteHost = $WriteHost $newType.WriteOutput = $WriteOutput foreach ($param in $PSBoundParameters.Keys) { switch ($param) { "Prefix" { $newType.Prefix = $Prefix break } "Color" { $newType.Color = $Color break } "LogPath" { $newType.LogPath = $LogPath break } "FormatBlock" { $newType.FormatBlock = $FormatBlock break } "OutputBlock" { $newType.OutputBlock = $OutputBlock break } } } $script:LoggerTypes[$Name] = $newType if ($Default) { Write-Verbose "Setting default logger type to ${Name}" $script:LoggerDefault = $Name } Get-LoggerType $Name } } <# .SYNOPSIS Returns all Logger Types or a single Logger Type, if a name is referenced. Names may be passed by pipeline input. .PARAMETER Name The Name of the specific Logger Type to display #> Function Get-LoggerType { [CmdletBinding()] param( [Parameter(Mandatory=$false,Position=0,ValueFromPipeline)] [string]$Name = [string]::Empty ) process { $types = $script:LoggerTypes.Keys if ($PSBoundParameters.Keys -contains "Name" -and ![string]::IsNullOrEmpty($Name)) { if (!$script:LoggerTypes.ContainsKey($Name)) { throw New-Object ArgumentException -ArgumentList "Name supplied to Get-LoggerType does not exist" } $types = $($Name) } $types = $types | ForEach-Object { $_ } $types | ForEach-Object { New-Object LoggerType -ArgumentList $script:LoggerTypes[$_] } } } <# .SYNOPSIS Update-LoggerType updates an existing LoggerType with new options or may be used to remove options. LoggerType objects can be supplied by pipeline. .PARAMETER Name The name of the Logger Type to update .PARAMETER Prefix A string value to prefix the message with. This is performed after any FormatBlock script. .PARAMETER Color The Color to use when writing content via Write-Host. .PARAMETER LogPath Path to a file to write finalised message content to. Contents are appended and written in UTF8 format. .PARAMETER WriteHost Determine whether the message should be written to the console using Write-Host .PARAMETER WriteOutput Determine whether the message should be written as object output from the function .PARAMETER FormatBlock Script Block to be called for reformat the original message e.g. { "test: $_" } .PARAMETER OutputBlock Script Block to be called with the finalised message text. .PARAMETER Default Defines whether this Logger Type should be the default logger type #> Function Update-LoggerType { [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName)] [string]$Name, [Parameter(Mandatory=$false)] $Prefix = $null, [Parameter(Mandatory=$false)] [Nullable[System.ConsoleColor]]$Color = $null, [Parameter(Mandatory=$false)] $LogPath = $null, [Parameter(Mandatory=$false)] [switch]$WriteHost = $null, [Parameter(Mandatory=$false)] [switch]$WriteOutput = $null, [Parameter(Mandatory=$false)] [ScriptBlock]$FormatBlock = $null, [Parameter(Mandatory=$false)] [ScriptBlock]$OutputBlock = $null, [Parameter(Mandatory=$false)] [switch]$RemoveFormatBlock = $false, [Parameter(Mandatory=$false)] [switch]$RemoveOutputBlock = $false, [Parameter(Mandatory=$false)] [switch]$Default = $false ) process { if ([string]::IsNullOrEmpty($Name)) { throw New-Object ArgumentException -ArgumentList "Null or empty Name supplied to Update-LoggerType" } if (!$script:LoggerTypes.ContainsKey($Name)) { throw New-Object ArgumentException -ArgumentList "Name supplied to Update-LoggerType does not exist" } Write-Verbose "Updating logger type: ${Name}" $loggerType = $script:LoggerTypes[$Name] if ($RemoveFormatBlock) { Write-Verbose "Removing Format block for type (${Name})" $loggerType.FormatBlock = $null } if ($RemoveOutputBlock) { Write-Verbose "Removing Output block for type (${Name})" $loggerType.OutputBlock = $null } foreach ($param in $PSBoundParameters.Keys) { switch ($param) { "Prefix" { $loggerType.Prefix = $Prefix break } "Color" { $loggerType.Color = $Color break } "LogPath" { $loggerType.LogPath = $LogPath break } "WriteHost" { $loggerType.WriteHost = $WriteHost break } "WriteOutput" { $loggerType.WriteOutput = $WriteOutput break } "FormatBlock" { $loggerType.FormatBlock = $FormatBlock break } "OutputBlock" { $loggerType.OutputBlock = $OutputBlock break } "Default" { if ($Default -eq $true) { Write-Verbose "Setting Logger type (${Name}) as default." $script:LoggerDefault = $Name break } if ($script:LoggerDefault -eq $Name) { Write-Verbose "Logger type (${Name}) was default. Resetting default logger." $script:LoggerDefault = $null } break } } } Get-LoggerType $Name } } <# #> Function Remove-LoggerType { [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName)] [string]$Name = [string]::Empty ) process { if ([string]::IsNullOrEmpty($Name)) { throw New-Object ArgumentException -ArgumentList "Null or empty Name passed to Remove-LoggerType" } if (!$script:LoggerTypes.ContainsKey($Name)) { Write-Verbose "Logger type does not exist: ${Name}" return } Write-Verbose "Removing logger type: ${Name}" $null = $script:LoggerTypes.Remove($Name) if ($script:LoggerDefault -ne $null -and $script:LoggerDefault -eq $Name) { Write-Verbose "Logger type (${Name}) was default. Resetting default." $script:LoggerDefault = $null } } } <# #> Function Get-DefaultLoggerType { [CmdletBinding()] param() if ([string]::IsNullOrEmpty($script:LoggerDefault)) { Write-Verbose "No Logger default defined" return } if (!$script:LoggerTypes.Contains($script:LoggerDefault)) { # Shouldn't happen. LoggerDefault contains name, which doesn't exist. # reset logger default and return as though there is no default. Write-Verbose "Default logger doesn't exist in collection. Resetting default logger." $script:LoggerDefault = $null return } $default = $script:LoggerDefault Write-Verbose "Logger default: ${default}" Get-LoggerType $script:LoggerDefault } <# #> Function Reset-DefaultLoggerType { [CmdletBinding()] param() Write-Verbose "Resetting default logger type" $script:LoggerDefault = $null } <# #> Function Write-Logger { [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0)] [string]$Message, [Parameter(Mandatory=$false)] [string]$Name = [string]::Empty ) # Determine LoggerType name to use $type = $null if ($PSBoundParameters.Keys -contains "Type") { if ([string]::IsNullOrEmpty($Name) -or !$script:LoggerTypes.Contains($Name)) { throw New-Object ArgumentException -ArgumentList "Logger type specified (${Name}) does not exist" } $type = $script:LoggerTypes[$Name] } if ($type -eq $null -and ![string]::IsNullOrEmpty($script:LoggerDefault) -and $script:LoggerTypes.Contains($script:LoggerDefault)) { $type = $script:LoggerTypes[$script:LoggerDefault] } $color = $null $prefix = $null $formatBlock = $null $outputBlock = $null $writeHost = $true $writeOutput = $false $logPath = [string]::Empty if ($type -ne $null) { $prefix = $type.Prefix $color = $type.Color $formatBlock = $type.FormatBlock $outputBlock = $type.OutputBlock $writeHost = $type.WriteHost $writeOutput = $type.WriteOutput $logPath = $type.LogPath } # Default to Grey for colour if ($color -eq $null) { $color = [System.ConsoleColor]::Gray } $msg = $Message # Use format block to pre-process message, if defined if ($formatBlock -ne $null) { $msg = ($msg | ForEach-Object $formatBlock).ToString() } # Add prefix to message if (![string]::IsNullOrEmpty($prefix)) { $msg = [string]::Format("{0}{1}", $prefix, $msg) } # Write host output, if required if ($writeHost) { Write-Host -ForegroundColor $color $msg } # Write object output, if required if ($writeOutput) { Write-Output $msg } # Write to file, if defined if (![string]::IsNullOrEmpty($logPath)) { $msg | Out-File -Append -FilePath $logPath -Encoding UTF8 } # Send message to script block, if defined if ($outputBlock -ne $null) { $null = $msg | ForEach-Object $outputBlock } } |