Last active
March 14, 2025 02:34
-
-
Save barsv/85c93b599a763206f47aec150fb41ca0 to your computer and use it in GitHub Desktop.
Logging in powershell with log rotation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# all logging settins are here on top | |
$logFile = "log-$(gc env:computername).log" | |
$logLevel = "DEBUG" # ("DEBUG","INFO","WARN","ERROR","FATAL") | |
$logSize = 1mb # 30kb | |
$logCount = 10 | |
# end of settings | |
function Write-Log-Line ($line) { | |
Add-Content $logFile -Value $Line | |
Write-Host $Line | |
} | |
# http://stackoverflow.com/a/38738942 | |
Function Write-Log { | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory=$True)] | |
[string] | |
$Message, | |
[Parameter(Mandatory=$False)] | |
[String] | |
$Level = "DEBUG" | |
) | |
$levels = ("DEBUG","INFO","WARN","ERROR","FATAL") | |
$logLevelPos = [array]::IndexOf($levels, $logLevel) | |
$levelPos = [array]::IndexOf($levels, $Level) | |
$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss:fff") | |
if ($logLevelPos -lt 0){ | |
Write-Log-Line "$Stamp ERROR Wrong logLevel configuration [$logLevel]" | |
} | |
if ($levelPos -lt 0){ | |
Write-Log-Line "$Stamp ERROR Wrong log level parameter [$Level]" | |
} | |
# if level parameter is wrong or configuration is wrong I still want to see the | |
# message in log | |
if ($levelPos -lt $logLevelPos -and $levelPos -ge 0 -and $logLevelPos -ge 0){ | |
return | |
} | |
$Line = "$Stamp $Level $Message" | |
Write-Log-Line $Line | |
} | |
# https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Script-to-Roll-a96ec7d4 | |
function Reset-Log | |
{ | |
# function checks to see if file in question is larger than the paramater specified | |
# if it is it will roll a log and delete the oldes log if there are more than x logs. | |
param([string]$fileName, [int64]$filesize = 1mb , [int] $logcount = 5) | |
$logRollStatus = $true | |
if(test-path $filename) | |
{ | |
$file = Get-ChildItem $filename | |
if((($file).length) -ige $filesize) #this starts the log roll | |
{ | |
$fileDir = $file.Directory | |
#this gets the name of the file we started with | |
$fn = $file.name | |
$files = Get-ChildItem $filedir | ?{$_.name -like "$fn*"} | Sort-Object lastwritetime | |
#this gets the fullname of the file we started with | |
$filefullname = $file.fullname | |
#$logcount +=1 #add one to the count as the base file is one more than the count | |
for ($i = ($files.count); $i -gt 0; $i--) | |
{ | |
#[int]$fileNumber = ($f).name.Trim($file.name) #gets the current number of | |
# the file we are on | |
$files = Get-ChildItem $filedir | ?{$_.name -like "$fn*"} | Sort-Object lastwritetime | |
$operatingFile = $files | ?{($_.name).trim($fn) -eq $i} | |
if ($operatingfile) | |
{$operatingFilenumber = ($files | ?{($_.name).trim($fn) -eq $i}).name.trim($fn)} | |
else | |
{$operatingFilenumber = $null} | |
if(($operatingFilenumber -eq $null) -and ($i -ne 1) -and ($i -lt $logcount)) | |
{ | |
$operatingFilenumber = $i | |
$newfilename = "$filefullname.$operatingFilenumber" | |
$operatingFile = $files | ?{($_.name).trim($fn) -eq ($i-1)} | |
write-host "moving to $newfilename" | |
move-item ($operatingFile.FullName) -Destination $newfilename -Force | |
} | |
elseif($i -ge $logcount) | |
{ | |
if($operatingFilenumber -eq $null) | |
{ | |
$operatingFilenumber = $i - 1 | |
$operatingFile = $files | ?{($_.name).trim($fn) -eq $operatingFilenumber} | |
} | |
write-host "deleting " ($operatingFile.FullName) | |
remove-item ($operatingFile.FullName) -Force | |
} | |
elseif($i -eq 1) | |
{ | |
$operatingFilenumber = 1 | |
$newfilename = "$filefullname.$operatingFilenumber" | |
write-host "moving to $newfilename" | |
move-item $filefullname -Destination $newfilename -Force | |
} | |
else | |
{ | |
$operatingFilenumber = $i +1 | |
$newfilename = "$filefullname.$operatingFilenumber" | |
$operatingFile = $files | ?{($_.name).trim($fn) -eq ($i-1)} | |
write-host "moving to $newfilename" | |
move-item ($operatingFile.FullName) -Destination $newfilename -Force | |
} | |
} | |
} | |
else | |
{ $logRollStatus = $false} | |
} | |
else | |
{ | |
$logrollStatus = $false | |
} | |
$LogRollStatus | |
} | |
# to null to avoid output | |
$Null = @( | |
Reset-Log -fileName $logFile -filesize $logSize -logcount $logCount | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
. .\logger.ps1 | |
Write-Log "Started" "INFO" | |
for ($i = 100; $i -gt 0; $i--) | |
{ | |
Write-Log "debug message" | |
Write-Log "debug message2" "DEBUG" | |
Write-Log "info message" "INFO" | |
Write-Log "warn message" "WARN" | |
Write-Log "error message" "ERROR" | |
Write-Log "fatal message" "FATAL" | |
Write-Log "message with wrong level" "WRONG" | |
} |
@mntlfngs
Its probably because a list was one, and powershell interprets that by removing list unless using @(). I couldn't reproduce the problem, but I have added those, to be safe. I also fixed it so it works without extensions on log-file.
@arberg
Thanks. I got time to tinker and did some changes that made it work for me. Created a fork with my mods .
Just updated my fork with something that I think is working pretty slick now. Quite happy with it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@arberg
It seems like the roll only works when there are more than 1 file to start. Otherwise I get error "The property 'count' cannot be found on this object." Am I missing something? Sorry I don't have a fix for it at this point (except that I copy/renamed my log so it would have 2) but I'll be working on it as I get time.