Public/Write-Log.ps1
|
Function Write-Log { <# .SYNOPSIS Writing log messages into a logfile and additionally to the console output. The messages are also redirected to the Apteco software, if used in a custom channel .DESCRIPTION The logfile getting written looks like 20210217134552 a6f3eda5-1b50-4841-861e-010174784e8c INFO Hello World 20210217134617 a6f3eda5-1b50-4841-861e-010174784e8c ERROR Hello World separated by tabs. Make sure, the variables $logfile and $processId are present before calling this. Otherwise they will be created automatically. The variables could be filled like $logfile = ".\test.log" $processId = [guid]::NewGuid() The process id is good for parallel calls so you know they belong together .PARAMETER Message The message the script should log into a file and additionally to the console .PARAMETER WriteToHostToo Boolean flag (default=true) to let the function put the message additionally to the console .PARAMETER Severity Uses the enum [LogSeverity] (default=[LogSeverity]::VERBOSE) to choose the loglevel. The logfile will contain that loglevel and depending on error or warning, it will be shown in the console .PARAMETER UtcTimestamp Log the current entry in UTC rather than the local time .EXAMPLE Write-Log -message "Hello World" .EXAMPLE Write-Log -message "Hello World" -severity ([LogSeverity]::ERROR) .EXAMPLE "Hello World" | Write-Log .EXAMPLE Write-Log -message "Hello World" -WriteToHostToo $false .INPUTS String .OUTPUTS $null .NOTES Author: florian.von.bracht@apteco.de #> [cmdletbinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline)] [ValidateNotNullOrEmpty()] [String]$Message ,[Parameter(Mandatory=$false)] [Boolean]$WriteToHostToo = $true ,[Parameter(Mandatory=$false)] [LogSeverity]$Severity = [LogSeverity]::VERBOSE ,[Parameter(Mandatory=$false)] [Switch]$UtcTimestamp = $false ) Begin { # Testing the path If ( ( Test-Path -Path $Script:logfile -IsValid ) -eq $false ) { Write-Error -Message "Invalid variable '`$logfile'. The path '$( $Script:logfile )' is invalid." throw "Invalid path for logfile. The path '$( $Script:logfile )' is invalid." } # Check on $Message If ( $null -eq $Message ) { Write-Error -Message "Invalid variable '`$Message'. The message '$( $Message )' is invalid." throw "Invalid log message. The message '$( $Message )' is invalid." } } Process { $vs = $Script:valueStore.Clone() If ($UtcTimestamp -eq $True) { $vs.Add("TIMESTAMP", [datetime]::UtcNow.ToString( $Script:defaultTimestampFormat ) ) } else { $vs.Add("TIMESTAMP", [datetime]::Now.ToString( $Script:defaultTimestampFormat ) ) } $vs.Add("PROCESSID", $Script:processId) $vs.Add("SEVERITY", $Severity.ToString()) $vs.Add("MESSAGE", $Message) $vs.Add("PROCRAM", [math]::Round([System.Diagnostics.Process]::GetCurrentProcess().WorkingSet64 / 1MB, 3)) $vs.Add("PROCCPU", [math]::Round([System.Diagnostics.Process]::GetCurrentProcess().CPU, 3)) $pattern = ($vs.Keys | ForEach-Object { [regex]::Escape($_) }) -join '|' $logstring = [regex]::Replace($Script:defaultOutputFormat, $pattern, { param($match) $vs[$match.Value] }) # Save the string to the logfile $randomDelay = Get-Random -Maximum 3000 $outArgs = @{ FilePath = $script:logfile InputObject = $logstring.toString() Encoding = "utf8" Append = $true NoClobber = $true } Invoke-CommandRetry -Command 'Out-File' -Args $outArgs -retries 10 -MillisecondsDelay $randomDelay | Out-Null # Additional logfiles If ( $Script:additionalLogs.Count -gt 0 ) { ForEach ( $addLog in $Script:additionalLogs ) { Switch ( $addLog.Type ) { "textfile" { $addLogArgs = @{ FilePath = $addLog.Options.Path InputObject = $logstring.toString() Encoding = "utf8" Append = $true NoClobber = $true } Invoke-CommandRetry -Command 'Out-File' -Args $addLogArgs -retries 10 -MillisecondsDelay $randomDelay | Out-Null } # TODO add database support in future Default { Write-Warning -Message "Unknown additional log type '$( $addLog.Type )' for additional log '$( $addLog.Name )'." } } } } # Put the string to host, too If ( $WriteToHostToo -eq $true ) { # Write-Host $message # Updating to the newer streams Information, Verbose, Error and Warning Switch ( $Severity ) { ( [LogSeverity]::VERBOSE ) { #Write-Verbose $message $message -Verbose # To always show the logmessage without verbose flag, execute $VerbosePreference = "Continue" Write-Verbose -Message $Message -InformationAction Continue -Verbose } ( [LogSeverity]::INFO ) { Write-Information -MessageData "INFO: $( $Message )" -Tags @("Info") -Verbose # -InformationAction Continue } ( [LogSeverity]::WARNING ) { Write-Warning -Message $Message } ( [LogSeverity]::ERROR ) { Write-Error -Message $Message -CategoryActivity "ERROR" } Default { #Write-Verbose -Message $message -Verbose Write-Verbose -Message $Message -Verbose # -InformationAction Continue } } } } End { } } |