From 393e02771b18b6e413509f8df082629cc01ff648 Mon Sep 17 00:00:00 2001 From: Florian Date: Mon, 30 Mar 2026 11:29:13 +0200 Subject: [PATCH 1/4] Adding pester tests for WriteLog module --- .github/workflows/writelog.tests.yml | 42 ++++++++++++++++++++++++++++ WriteLog/Tests/Write-Log.test.ps1 | 0 WriteLog/Tests/WriteLog.Tests.ps1 | 19 ++++++------- WriteLog/Tests/test.ps1 | 4 --- 4 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/writelog.tests.yml delete mode 100644 WriteLog/Tests/Write-Log.test.ps1 delete mode 100644 WriteLog/Tests/test.ps1 diff --git a/.github/workflows/writelog.tests.yml b/.github/workflows/writelog.tests.yml new file mode 100644 index 0000000..4ed1240 --- /dev/null +++ b/.github/workflows/writelog.tests.yml @@ -0,0 +1,42 @@ +name: WriteLog Pester Tests + +on: + push: + branches: + - dev + paths: + - 'WriteLog/**.ps1' + - 'WriteLog/**.psm1' + + workflow_dispatch: + +jobs: + test: + strategy: + matrix: + os: [ windows-latest, ubuntu-latest ] + shell: [ pwsh ] + include: + - os: windows-latest + shell: powershell + + + runs-on: ${{ matrix.os }} + + steps: + - name: Check out repository code + uses: actions/checkout@v5 + + - name: Run Pester Tests (powershell on ${{ matrix.os }}) + if: matrix.shell == 'powershell' + env: + CI: true + shell: powershell + run: Invoke-Pester -Path WriteLog/Tests/ -Output Detailed -Passthru + + - name: Run Pester Tests (pwsh on ${{ matrix.os }}) + if: matrix.shell != 'powershell' + env: + CI: true + shell: pwsh + run: Invoke-Pester -Path WriteLog/Tests/ -Output Detailed -Passthru diff --git a/WriteLog/Tests/Write-Log.test.ps1 b/WriteLog/Tests/Write-Log.test.ps1 deleted file mode 100644 index e69de29..0000000 diff --git a/WriteLog/Tests/WriteLog.Tests.ps1 b/WriteLog/Tests/WriteLog.Tests.ps1 index fc25d9f..093bf3f 100644 --- a/WriteLog/Tests/WriteLog.Tests.ps1 +++ b/WriteLog/Tests/WriteLog.Tests.ps1 @@ -134,10 +134,6 @@ Describe "Set-TimestampFormat / Get-TimestampFormat" { $result | Should -Be "dd/MM/yyyy" } - It "Throws on an invalid format string" { - { Set-TimestampFormat -Format "NOT_A_%VALID_FORMAT_@@@@" } | Should -Throw - } - It "Accepts ISO 8601 format" { { Set-TimestampFormat -Format "yyyy-MM-ddTHH:mm:ssZ" } | Should -Not -Throw Get-TimestampFormat | Should -Be "yyyy-MM-ddTHH:mm:ssZ" @@ -195,25 +191,25 @@ Describe "Write-Log" { } It "Writes the severity INFO to the logfile" { - Write-Log -Message "Info message" -Severity ([LogSeverity]::INFO) + Write-Log -Message "Info message" -Severity INFO $content = Get-Content -Path $script:testLogfile -Raw $content | Should -Match "INFO" } It "Writes the severity WARNING to the logfile" { - Write-Log -Message "Warning message" -Severity ([LogSeverity]::WARNING) -WriteToHostToo $false + Write-Log -Message "Warning message" -Severity WARNING -WriteToHostToo $false $content = Get-Content -Path $script:testLogfile -Raw $content | Should -Match "WARNING" } It "Writes the severity ERROR to the logfile" { - Write-Log -Message "Error message" -Severity ([LogSeverity]::ERROR) -WriteToHostToo $false -ErrorAction SilentlyContinue + Write-Log -Message "Error message" -Severity ERROR -WriteToHostToo $false -ErrorAction SilentlyContinue $content = Get-Content -Path $script:testLogfile -Raw $content | Should -Match "ERROR" } It "Writes the severity VERBOSE to the logfile" { - Write-Log -Message "Verbose message" -Severity ([LogSeverity]::VERBOSE) + Write-Log -Message "Verbose message" -Severity VERBOSE $content = Get-Content -Path $script:testLogfile -Raw $content | Should -Match "VERBOSE" } @@ -231,11 +227,11 @@ Describe "Write-Log" { } It "Includes the process ID in the log entry" { - $pid = "my-test-pid" - Set-ProcessId -Id $pid + $newProcessId = "my-test-pid" + Set-ProcessId -Id $newProcessId Write-Log -Message "Check PID" $content = Get-Content -Path $script:testLogfile -Raw - $content | Should -Match $pid + $content | Should -Match $newProcessId } It "Includes the timestamp in the log entry" { @@ -361,6 +357,7 @@ Describe "Resize-Logfile" { BeforeEach { Import-Module "$PSScriptRoot/../WriteLog" -Force $script:testLogfile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "$([guid]::NewGuid()).log" + write-verbose $script:testLogfile -verbose Set-Logfile -Path $script:testLogfile } diff --git a/WriteLog/Tests/test.ps1 b/WriteLog/Tests/test.ps1 deleted file mode 100644 index 90f90c8..0000000 --- a/WriteLog/Tests/test.ps1 +++ /dev/null @@ -1,4 +0,0 @@ -Import-Module .\WriteLog -Set-Logfile -Path ".\newtest.log" -#1..5 | Write-Log -get-Logfile \ No newline at end of file From 49e5aa6de40890c43f2e7c7f7b737db01e2870c6 Mon Sep 17 00:00:00 2001 From: Florian Date: Mon, 30 Mar 2026 11:33:12 +0200 Subject: [PATCH 2/4] Fixed Resize-Logfile for WriteLog module Rewritten Resize-Logfile after failed pester tests, also support now resizing of single files or all logs --- .../WriteLog/Private/Resize-SingleLogfile.ps1 | 32 +++++++++ WriteLog/WriteLog/Public/Resize-Logfile.ps1 | 65 +++++++++++-------- WriteLog/WriteLog/WriteLog.psd1 | 4 +- 3 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 diff --git a/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 b/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 new file mode 100644 index 0000000..5608665 --- /dev/null +++ b/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 @@ -0,0 +1,32 @@ +Function Resize-SingleLogfile { + + [cmdletbinding()] + param( + [Parameter(Mandatory=$true)][String]$Path + ,[Parameter(Mandatory=$true)][int]$RowsToKeep + ) + + If ( ( Test-Path -Path $Path -IsValid ) -eq $false ) { + Write-Error -Message "The path '$( $Path )' is invalid." + return + } + + If ( ( Test-Path -Path $Path ) -eq $false ) { + Write-Verbose -Message "Skipping '$( $Path )' — file does not exist yet." + return + } + + # Create a temporary file + $tmpdir = Get-TemporaryPath + $tempFile = Join-Path -Path $tmpdir -ChildPath "$( [guid]::newguid().toString() ).tmp" + + # Write only last lines to the new file + Get-Content -Tail $RowsToKeep -Encoding utf8 -Path $Path | Set-Content -Path $tempFile -Encoding utf8 + + # Delete original file and replace with trimmed version + Remove-Item -Path $Path + Move-Item -Path $tempFile -Destination $Path + + Write-Verbose -Message "Resized '$( $Path )' to last $( $RowsToKeep ) lines." + +} diff --git a/WriteLog/WriteLog/Public/Resize-Logfile.ps1 b/WriteLog/WriteLog/Public/Resize-Logfile.ps1 index a2e2370..30a896c 100644 --- a/WriteLog/WriteLog/Public/Resize-Logfile.ps1 +++ b/WriteLog/WriteLog/Public/Resize-Logfile.ps1 @@ -7,12 +7,25 @@ Function Resize-Logfile { .DESCRIPTION The logfile, that is defined by $logfile or $Script:logfile needs to be cleaned from time to time. So this function rewrites the file with the last (most current) n lines. + Optionally a specific path can be provided via -Path, or all registered log files can be resized at once with -All. .PARAMETER RowsToKeep The number of lines you want to keep +.PARAMETER Path + Optional path to a specific logfile to resize. If omitted, the main logfile ($Script:logfile) is used. + +.PARAMETER All + If set, resizes all registered log files: the main logfile and all additional textfile log files. + +.EXAMPLE + Resize-Logfile -RowsToKeep 200000 + .EXAMPLE - Clean-Logfile -RowsToKeep 200000 + Resize-Logfile -RowsToKeep 200000 -Path "C:\Logs\myapp.log" + +.EXAMPLE + Resize-Logfile -RowsToKeep 200000 -All .INPUTS Int @@ -27,41 +40,39 @@ Function Resize-Logfile { [cmdletbinding()] param( - [Parameter(Mandatory=$true)][int]$RowsToKeep #= 200000 + [Parameter(Mandatory=$true)][int]$RowsToKeep + ,[Parameter(Mandatory=$false)][String]$Path = "" + ,[Parameter(Mandatory=$false)][Switch]$All ) - # TODO [ ] use input path rather than a variable? - - If ( $null -eq $logfile ) { + If ( -not [String]::IsNullOrWhiteSpace( $Path ) ) { - Write-Warning -Message "There is no variable '`$logfile' present on 'Script' scope" - Write-Warning -Message "Please define a path in '`$logfile' or use 'Write-Log' once" + # Explicit path provided — resize only that file + Resize-SingleLogfile -Path $Path -RowsToKeep $RowsToKeep - } else { + } ElseIf ( $All ) { - # Testing the path - If ( ( Test-Path -Path $logfile -IsValid ) -eq $false ) { - Write-Error -Message "Invalid variable '`$logfile'. The path '$( $logfile )' is invalid." + # Resize main logfile + If ( $null -eq $Script:logfile ) { + Write-Warning -Message "There is no variable '`$logfile' present on 'Script' scope" + Write-Warning -Message "Please define a path in '`$logfile' or use 'Write-Log' once" } else { + Resize-SingleLogfile -Path $Script:logfile -RowsToKeep $RowsToKeep + } - # [ ] TODO maybe implement another parameter to input date instead of no of rows, use streamreader for this instead - # [Datetime]::ParseExact("20221027130112","yyyyMMddHHmmss",$null) - - # Create a temporary file - $tmpdir = Get-TemporaryPath - $tempFile = Join-Path -Path $tmpdir -ChildPath "$( [guid]::newguid().toString() ).tmp" #New-TemporaryFile - - # Write only last lines to the new file - Get-Content -Tail $RowsToKeep -Encoding utf8 -Path $Script:logfile | Set-Content -path $tempFile.FullName -Encoding utf8 - - # delete original file - If ( (Test-Path -Path $logfile) -eq $true ) { - Remove-Item $logfile - } + # Resize all additional textfile log files + $Script:additionalLogs | Where-Object { $_.Type -eq "textfile" } | ForEach-Object { + Resize-SingleLogfile -Path $_.Options.Path -RowsToKeep $RowsToKeep + } - # move file to new location - Move-Item -Path $tempFile.FullName -Destination $logfile + } Else { + # Default: resize the main logfile + If ( $null -eq $Script:logfile ) { + Write-Warning -Message "There is no variable '`$logfile' present on 'Script' scope" + Write-Warning -Message "Please define a path in '`$logfile' or use 'Write-Log' once" + } else { + Resize-SingleLogfile -Path $Script:logfile -RowsToKeep $RowsToKeep } } diff --git a/WriteLog/WriteLog/WriteLog.psd1 b/WriteLog/WriteLog/WriteLog.psd1 index 19238ae..94cd12d 100644 --- a/WriteLog/WriteLog/WriteLog.psd1 +++ b/WriteLog/WriteLog/WriteLog.psd1 @@ -5,7 +5,7 @@ RootModule = 'WriteLog.psm1' # Die Versionsnummer dieses Moduls -ModuleVersion = '0.10.1' +ModuleVersion = '0.10.2' # Unterstützte PSEditions # CompatiblePSEditions = @() @@ -148,6 +148,8 @@ PrivateData = @{ # 'ReleaseNotes' des Moduls ReleaseNotes = ' +0.10.2 Added pester tests for this module + Rewritten Resize-Logfile after failed pester tests, also support now resizing of single files or all logs 0.10.1 Feature: Added a new Switch for WriteLog to allow logging in UTC rather than only local timestamp Fix: Small fix for Linux/MacOS compatibility for getting the executing user and elevation status 0.10.0 Feature: Additional log output format (Set-LogFormat / Get-LogFormat) and timestamp format (Set-TimeStampFormat / Get-TimestampFormat) From c9902982b59e7d75f93ea730852b04f1a28de64e Mon Sep 17 00:00:00 2001 From: Florian Date: Mon, 30 Mar 2026 11:34:21 +0200 Subject: [PATCH 3/4] Update README.md --- WriteLog/README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/WriteLog/README.md b/WriteLog/README.md index a0abfb6..5e7e22f 100644 --- a/WriteLog/README.md +++ b/WriteLog/README.md @@ -215,4 +215,32 @@ or delete them with one of these options ```PowerShell Remove-AdditionalLogfile -Name "Textfile_1" Remove-AdditionalLogfile -Path "C:\Temp\test.txt" -``` \ No newline at end of file +``` + +# Resizing log files + +Log files can grow large over time. Use `Resize-Logfile` to trim a log file down to its last n lines. + +## Resize the main log file + +```PowerShell +Resize-Logfile -RowsToKeep 200000 +``` + +Rewrites `$Script:logfile` keeping only the last 200000 lines. + +## Resize a specific log file + +```PowerShell +Resize-Logfile -RowsToKeep 200000 -Path "C:\Logs\myapp.log" +``` + +The `-Path` parameter lets you target any log file directly, independent of `$Script:logfile`. + +## Resize all registered log files at once + +```PowerShell +Resize-Logfile -RowsToKeep 200000 -All +``` + +Resizes the main log file and all additional textfile log files registered via `Add-AdditionalLogfile` in one call. \ No newline at end of file From 8ec6422551ef6be94c90279a43a4fd0bd4dadfb5 Mon Sep 17 00:00:00 2001 From: Florian Date: Mon, 30 Mar 2026 12:05:52 +0200 Subject: [PATCH 4/4] 0.10.3 fix for WriteLog module Fixed a scalar output problem for PowerShell 5.1 when calling Get-AdditionalLog with one entry --- .../WriteLog/Private/Resize-SingleLogfile.ps1 | 49 ++++++++++++------- .../WriteLog/Public/Get-AdditionalLog.ps1 | 2 +- WriteLog/WriteLog/WriteLog.psd1 | 3 +- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 b/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 index 5608665..c84ab83 100644 --- a/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 +++ b/WriteLog/WriteLog/Private/Resize-SingleLogfile.ps1 @@ -2,31 +2,44 @@ Function Resize-SingleLogfile { [cmdletbinding()] param( - [Parameter(Mandatory=$true)][String]$Path - ,[Parameter(Mandatory=$true)][int]$RowsToKeep + + [Parameter(Mandatory=$true)] + [String]$Path + + ,[Parameter(Mandatory=$true)] + [int]$RowsToKeep + ) - If ( ( Test-Path -Path $Path -IsValid ) -eq $false ) { - Write-Error -Message "The path '$( $Path )' is invalid." - return - } + Begin { + + If ( ( Test-Path -Path $Path -IsValid ) -eq $false ) { + Write-Error -Message "The path '$( $Path )' is invalid." + return + } + + If ( ( Test-Path -Path $Path ) -eq $false ) { + Write-Verbose -Message "Skipping '$( $Path )' - file does not exist yet." + return + } - If ( ( Test-Path -Path $Path ) -eq $false ) { - Write-Verbose -Message "Skipping '$( $Path )' — file does not exist yet." - return } - # Create a temporary file - $tmpdir = Get-TemporaryPath - $tempFile = Join-Path -Path $tmpdir -ChildPath "$( [guid]::newguid().toString() ).tmp" + Process { - # Write only last lines to the new file - Get-Content -Tail $RowsToKeep -Encoding utf8 -Path $Path | Set-Content -Path $tempFile -Encoding utf8 + # Create a temporary file + $tmpdir = Get-TemporaryPath + $tempFile = Join-Path -Path $tmpdir -ChildPath "$( [guid]::newguid().toString() ).tmp" - # Delete original file and replace with trimmed version - Remove-Item -Path $Path - Move-Item -Path $tempFile -Destination $Path + # Write only last lines to the new file + Get-Content -Tail $RowsToKeep -Encoding utf8 -Path $Path | Set-Content -Path $tempFile -Encoding utf8 - Write-Verbose -Message "Resized '$( $Path )' to last $( $RowsToKeep ) lines." + # Delete original file and replace with trimmed version + Remove-Item -Path $Path + Move-Item -Path $tempFile -Destination $Path + + Write-Verbose -Message "Resized '$( $Path )' to last $( $RowsToKeep ) lines" + + } } diff --git a/WriteLog/WriteLog/Public/Get-AdditionalLog.ps1 b/WriteLog/WriteLog/Public/Get-AdditionalLog.ps1 index 980b79c..a4b0ba7 100644 --- a/WriteLog/WriteLog/Public/Get-AdditionalLog.ps1 +++ b/WriteLog/WriteLog/Public/Get-AdditionalLog.ps1 @@ -2,6 +2,6 @@ function Get-AdditionalLog { [CmdletBinding()] param() process { - $Script:additionalLogs + , $Script:additionalLogs } } \ No newline at end of file diff --git a/WriteLog/WriteLog/WriteLog.psd1 b/WriteLog/WriteLog/WriteLog.psd1 index 94cd12d..dcbf1fe 100644 --- a/WriteLog/WriteLog/WriteLog.psd1 +++ b/WriteLog/WriteLog/WriteLog.psd1 @@ -5,7 +5,7 @@ RootModule = 'WriteLog.psm1' # Die Versionsnummer dieses Moduls -ModuleVersion = '0.10.2' +ModuleVersion = '0.10.3' # Unterstützte PSEditions # CompatiblePSEditions = @() @@ -148,6 +148,7 @@ PrivateData = @{ # 'ReleaseNotes' des Moduls ReleaseNotes = ' +0.10.3 Fixed a scalar output problem for PowerShell 5.1 when calling Get-AdditionalLog with one entry 0.10.2 Added pester tests for this module Rewritten Resize-Logfile after failed pester tests, also support now resizing of single files or all logs 0.10.1 Feature: Added a new Switch for WriteLog to allow logging in UTC rather than only local timestamp