SmartLogging.psm1
Add-Type -TypeDefinition @"
public enum LogLevel { Trc = 0, Dbg = 1, Inf = 2, Wrn = 3, Err = 4, Cri = 5, Non = 6 } "@ $defaultLogLevel = [LogLevel]::Inf $defaultLogLevelString = @{ Short = 'inf' Long = 'info' Color = ([ConsoleColor]::White) } $consoleLogDateFormat = 'HH:mm:ss' $fileLogDateFormat = 'yyyy-MM-ddTHH:mm:ss zzz' $fileLogger = @{} function GetLogLevel($logLevel) { switch ($logLevel) { ( { $logLevel -ieq 'trace' -or $logLevel -ieq 'trc' }) { return [LogLevel]::Trc } ( { $logLevel -ieq 'debug' -or $logLevel -ieq 'dbg' }) { return [LogLevel]::Dbg } ( { $logLevel -ieq 'info' -or $logLevel -ieq 'inf' }) { return [LogLevel]::Inf } ( { $logLevel -ieq 'warning' -or $logLevel -ieq 'wrn' }) { return [LogLevel]::Wrn } ( { $logLevel -ieq 'error' -or $logLevel -ieq 'err' }) { return [LogLevel]::Err } ( { $logLevel -ieq 'critic' -or $logLevel -ieq 'cri' }) { return [LogLevel]::Cri } ( { $logLevel -ieq 'none' -or $logLevel -ieq 'non' }) { return [LogLevel]::Non } Default { return $null } } } function GetLogLevelInfo($logLevel) { switch ($logLevel) { ([LogLevel]::Trc) { return @{ Short = 'trc' Long = 'trace' Color = ([ConsoleColor]::DarkGray) } } ([LogLevel]::Dbg) { return @{ Short = 'dbg' Long = 'debug' Color = ([ConsoleColor]::DarkGray) } } ([LogLevel]::Inf) { return @{ Short = 'inf' Long = 'info' Color = ([ConsoleColor]::White) } } ([LogLevel]::Wrn) { return @{ Short = 'wrn' Long = 'warning' Color = ([ConsoleColor]::Yellow) } } ([LogLevel]::Err) { return @{ Short = 'err' Long = 'error' Color = ([ConsoleColor]::Red) } } ([LogLevel]::Cri) { return @{ Short = 'cri' Long = 'critical' Color = ([ConsoleColor]::Red) } } ([LogLevel]::Non) { return @{ Short = 'non' Long = 'none' Color = ([ConsoleColor]::White) } } Default { return $defaultLogLevelString } } } function GetUserLogLevel() { $userLogLevel = $env:LOGLEVEL if (-not $userLogLevel) { $userLogLevel = $defaultLogLevel } return (GetLogLevel $userLogLevel) } function ShouldLog($userLogLevel, $logLevel) { switch ($userLogLevel) { ( { ($logLevel.value__ -ge $userLogLevel.value__) -and ($userLogLevel -ne [LogLevel]::Non) -and ($logLevel -ne [LogLevel]::Non) }) { return $true } Default { return $false } } } function LogConsole($logLevelInfo, $value) { Write-Host "[$(Get-Date -Format $consoleLogDateFormat) " -NoNewline -ForegroundColor ([ConsoleColor]::DarkGray) Write-Host "$($logLevelInfo.Short.ToUpper())" -NoNewline -ForegroundColor $logLevelInfo.Color Write-Host "] " -NoNewline -ForegroundColor ([ConsoleColor]::DarkGray) Write-Host $value -ForegroundColor ([ConsoleColor]::White) } function LogFile($logLevelInfo, $value) { # Check logs folder and create when not exists $date = '{0:yyyy-MM-dd}' -f (Get-Date) if (-not ( Test-Path -Path $fileLogger.Dir -PathType Container)) { New-Item -Path $fileLogger.Dir -ItemType Container > $null } # Create log file in format '{current_date}_[${filelogger.FileName}].log' if ($fileLogger.FileName) { $logfile = "$date`_$($fileLogger.FileName).log" } else { $logfile = "$date.log" } $logFilePath = Join-Path $fileLogger.Dir $logfile $item = "[$(Get-Date -Format $fileLogDateFormat) " $item += "$($logLevelInfo.Long.ToUpper())]".PadRight(9) $item += " " $item += $value Add-Content -Path $logFilePath -Value "$item" -Encoding ascii > $null } function Log { [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline)] [string] $Value, [Parameter(ValueFromPipeline)] [string] $LogLevel ) begin { $level = $null if (-not $LogLevel -and -not $Value) { $level = $defaultLogLevel } elseif ($LogLevel -and -not $Value) { $level = GetLogLevel $LogLevel } elseif (-not $LogLevel -and $Value) { $level = GetLogLevel $Value } elseif ($LogLevel -and $Value) { $level = GetLogLevel $LogLevel if ($level -eq $null) { $level = GetLogLevel $Value } } if ($level -eq $null) { $level = $defaultLogLevel } } process { if (-not (ShouldLog (GetUserLogLevel) $level)) { return } $logLevelInfo = GetLogLevelInfo $level LogConsole $logLevelInfo $Value if ($fileLogger.IsEnabled) { LogFile $logLevelInfo $Value } } } function Set-FileLogger($Dir = 'logs', $FileName = '') { $Script:fileLogger.IsEnabled = $true $Script:fileLogger.Dir = $Dir $Script:fileLogger.FileName = $FileName } function Remove-FileLogger() { Set-FileLogger $Script:fileLogger.IsEnabled = $false } function Write-Status { [CmdletBinding()] param( [int] $Current, [int] $Total, [string] $Statustext, [string] $CurrentStatusText, [int] $ProgressbarLength = 35 ) # Save current Cursorposition for later [int]$XOrg = $Host.UI.RawUI.CursorPosition.X # Create Progressbar [string]$progressbar = "" for ($i = 0 ; $i -lt $([System.Math]::Round($(([System.Math]::Round(($($Current) / $Total) * 100, 2) * $ProgressbarLength) / 100), 0)); ++$i) { $progressbar = $progressbar + $([char]9608) } for ($i = 0 ; $i -lt ($ProgressbarLength - $([System.Math]::Round($(([System.Math]::Round(($($Current) / $Total) * 100, 2) * $ProgressbarLength) / 100), 0))); ++$i) { $progressbar = $progressbar + $([char]9617) } # Overwrite Current Line with the current Status Write-Host -NoNewline "`r$Statustext $progressbar [$($Current.ToString("#,###").PadLeft($Total.ToString("#,###").Length)) / $($Total.ToString("#,###"))] ($($(($Current / $Total) * 100).ToString("##0.00").PadLeft(6)) %) $CurrentStatusText" # There might be old Text behing the current Currsor, so let's write some blanks to the Position of $XOrg [int]$XNow = $Host.UI.RawUI.CursorPosition.X for ([int]$i = $XNow; $i -lt $XOrg; ++$i) { Write-Host -NoNewline " " } # Just for optical reasons: Go back to the last Position of current Line for ([int]$i = $XNow; $i -lt $XOrg; ++$i) { Write-Host -NoNewline "`b" } } |