PSOutLog.psm1
$color = @{ "[INFO]" = "Green" "[WARN]" = "Yellow" "[ERR]" = "Red" "Purple" = $PSStyle.Foreground.FromRgb(0xa020f0) "Orange" = $PSStyle.Foreground.FromRgb(0xffb618) "DeepYellow" = $PSStyle.Foreground.FromRgb(0xfff640) } $keyword = @("START", "END", "STEP") function Add-Logging ([string]$str, [string]$lvl, [int]$indent = 0) { $psPath = (Get-PSCallStack)[2].ScriptName $slash = ($IsWindows) ? "\" : "/" $path = ($psPath -and $psPath -notcontains ".psm1") ? $psPath.Replace($slash + $psPath.Split($slash)[-1], "") : "." $logPath = "$path/logs/$($psPath ? $psPath.Split($slash)[-1].Split('.ps1')[0] : '')$($env:PSOUTLOG_FILE_DATE_FORMAT ? "_" + $(Get-Date -Format $env:PSOUTLOG_FILE_DATE_FORMAT) : '').log" if (!(Test-Path $logPath)) { New-Item $logPath -Force } $strIndent = "" 0..($indent * 2) | ForEach-Object { if ($_ -gt 0) { $strIndent += " " } } $logStr = "$(Get-Date -Format ($env:PSOUTLOG_LOG_DATE_FORMAT ? $env:PSOUTLOG_LOG_DATE_FORMAT : "yyyy-MM-dd HH:mm:ss.fff"))`t$lvl $strIndent$str" foreach ($item in $keyword) { if ($logStr -cmatch $item) { $writeStr = ($writeStr ? $writeStr : $logStr) -replace $item, "$($color.Orange)$item$($PSStyle.Reset)" } } $boldStr = $logStr -match " : " ? $logStr -split " : " : $null if ($boldStr -and $boldStr[1]) { $writeStr = ($writeStr ? $writeStr : $logStr) -replace $boldStr[-1], "$($color.Purple)$($boldStr[-1])" } $writeStr = $writeStr ? $writeStr : $logStr Write-Host $writeStr -ForegroundColor:$color[$lvl] Add-Content -Path $logPath -Value $logStr } <# .SYNOPSIS Writes an informational/warning/error log message and creates a log file if it doesn't exist. .DESCRIPTION Out-Log writes the given message with informational log level. You can add indent level to make the log more readable. .PARAMETER str The log message to write. .EXAMPLE Out-Log "This is an info message" Out-WarnLog "This is a warning message" 1 Out-ErrLog "This is an error message" 2 #> function Out-Log ([string]$str, [int]$indent = 0) { Add-Logging $str "[INFO]" $indent } <# .SYNOPSIS Writes a warning log message. .DESCRIPTION Out-WarnLog writes the given message with warning log level. .PARAMETER str The log message to write. .EXAMPLE Out-WarnLog "This is a warning message" #> function Out-WarnLog ([string]$str, [int]$indent = 0) { Add-Logging $str "[WARN]" $indent } <# .SYNOPSIS Writes an error log message and terminates execution. .DESCRIPTION Out-ErrLog writes the given message with error log level and then exits the process. .PARAMETER str The log message to write. .EXAMPLE Out-ErrLog "This is an error message" #> function Out-ErrLog ([string]$str, [int]$indent = 0) { Add-Logging $str "[ERR]" $indent; exit; } <# .SYNOPSIS Writes a block of log messages. .DESCRIPTION Out-LogBlock writes a formatted block of log messages with a title and optional formatting based on a start or end marker. .PARAMETER title The title or message identifier for the log block. .PARAMETER startORend A flag indicating if this is the start or end of the log block. Acceptable values are "start" or "end". .PARAMETER indent The indentation level to apply to the log block. .EXAMPLE Out-LogBlock "$($MyInvocation.MyCommand.Name)" -startORend "start" -indent 0 Out-LogBlock "$($MyInvocation.MyCommand.Name)" -startORend "end" -indent 0 Out-LogBlock "$($MyInvocation.MyCommand.Name)" "start" 2 Out-LogBlock "$($MyInvocation.MyCommand.Name)" "end" 2 #> function Out-LogBlock ($title, [string][ValidateSet("start", "end")]$type = "start", [int]$indent = 1) { $charStep = @("≫", "—", "✧", "•", "∘", "・") $strLine = "" 1..(79 - ($indent * 2)) | ForEach-Object { $strLine += $charStep[$indent] } if ($type -eq "start") { Add-Logging $strLine "[INFO]" $indent } Add-Logging "$($strIndent)$($type.ToUpper()) : $title" "[INFO]" $indent if ($type -eq "end") { Add-Logging $strLine "[INFO]" $indent } } |