Classes/Logger.ps1
enum LogSeverity { Normal Warning Error } class LogMessage { [datetime]$DateTime = (Get-Date) [string]$Severity = [LogSeverity]::Normal [string]$LogLevel = [LogLevel]::Info [string]$Message [object]$Data LogMessage() { } LogMessage([string]$Message) { $this.Message = $Message } LogMessage([string]$Message, [object]$Data) { $this.Message = $Message $this.Data = $Data } LogMessage([LogSeverity]$Severity, [string]$Message, [object]$Data) { $this.Severity = $Severity $this.Message = $Message $this.Data = $Data } # Borrowed from https://github.com/PowerShell/PowerShell/issues/2736 hidden [string]Compact([string]$Json) { $indent = 0 $compacted = ($Json -Split '\n' | ForEach-Object { if ($_ -match '[\}\]]') { # This line contains ] or }, decrement the indentation level $indent-- } $line = (' ' * $indent * 2) + $_.TrimStart().Replace(': ', ': ') if ($_ -match '[\{\[]') { # This line contains [ or {, increment the indentation level $indent++ } $line }) -Join "`n" return $compacted } [string]ToJson() { $json = @{ DataTime = $this.DateTime Severity = $this.Severity LogLevel = $this.LogLevel Message = $this.Message Data = $this.Data } | ConvertTo-Json -Depth 100 -Compress return $json #return $this.Compact($json) } [string]ToString() { return $this.ToJson() } } class Logger { # The log directory [string]$LogDir hidden [string]$LogFile # Out logging level # Any log messages less than or equal to this will be logged [LogLevel]$LogLevel # The max size for the log files before rolling [int]$MaxSizeMB = 10 # Number of each log file type to keep [int]$FilesToKeep = 5 # Create logs files under provided directory Logger([string]$LogDir, [LogLevel]$LogLevel) { $this.LogDir = $LogDir $this.LogLevel = $LogLevel $this.LogFile = Join-Path -Path $this.LogDir -ChildPath 'PoshBot.log' $this.CreateLogFile() } # Create new log file or roll old log hidden [void]CreateLogFile() { if (Test-Path -Path $this.LogFile) { $this.RollLog($this.LogFile, $true) } Write-Debug -Message "[Logger:Logger] Creating log file [$($this.LogFile)]" New-Item -Path $this.LogFile -ItemType File -Force } [void]Info([LogMessage]$Message) { $Message.LogLevel = [LogLevel]::Info $this.Log($Message) } [void]Verbose([LogMessage]$Message) { $Message.LogLevel = [LogLevel]::Verbose $this.Log($Message) } [void]Debug([LogMessage]$Message) { $Message.LogLevel = [LogLevel]::Debug $this.Log($Message) } # Write out message in JSON form to log file [void]Log([LogMessage]$Message) { if ($global:VerbosePreference -eq 'Continue') { Write-Verbose -Message $Message.ToJson() } elseIf ($global:DebugPreference -eq 'Continue') { Write-Debug -Message $Message.ToJson() } if ($Message.LogLevel.value__ -le $This.LogLevel.value__) { $this.RollLog($this.LogFile, $false) $json = $Message.ToJson() $json | Out-File -FilePath $this.LogFile -Append -Encoding utf8 } } # Checks to see if file in question is larger than the max size specified for the logger. # If it is, it will roll the log and delete older logs to keep our number of logs per log type to # our max specifiex in the logger. # Specified $Always = $true will roll the log regardless hidden [void]RollLog([string]$LogFile, [bool]$Always) { if (Test-Path -Path $LogFile) { if ((($file = Get-Item -Path $logFile) -and ($file.Length/1mb) -gt $this.MaxSizeMB) -or $Always) { # Remove the last item if it would go over the limit if (Test-Path -Path "$logFile.$($this.FilesToKeep)") { Remove-Item -Path "$logFile.$($this.FilesToKeep)" } foreach ($i in $($this.FilesToKeep)..1) { if (Test-path -Path "$logFile.$($i-1)") { Move-Item -Path "$logFile.$($i-1)" -Destination "$logFile.$i" } } Move-Item -Path $logFile -Destination "$logFile.$i" $null = New-Item -Path $LogFile -Type File -Force | Out-Null } } } } |