@@ -61,162 +61,209 @@ function Format-NiceTimestamp {
6161 }
6262}
6363
64+ function Test-LogPageSize {
65+ param ($pageSize )
66+
67+ if ($pageSize -notmatch ' ^-?\d+$' ) {
68+ Show-Error - message " `n Invalid page size: $pageSize "
69+ return $false
70+ }
71+
72+ if ([int ]$pageSize -le 0 ) {
73+ Show-Error - message " `n Page size must be a positive integer."
74+ return $false
75+ }
76+
77+ return $true
78+ }
79+
80+ function Get-LogEntries {
81+ param ($path , $term = $null )
82+
83+ # Read the entire log file
84+ $logContent = Get-ContentWrapper - path $path - raw
85+
86+ # Split by the separator and filter out empty entries
87+ $logEntries = $logContent -split [regex ]::Escape($PVMConfig.constants.LOG_SEPARATOR ) | Where-Object - FilterScript { $_.Trim () -ne ' ' }
88+
89+ # Parse each entry into objects
90+ $parsedEntries = @ ()
91+ foreach ($entry in $logEntries ) {
92+ if ($term -and ($entry -notmatch [regex ]::Escape($term ))) {
93+ continue
94+ }
95+ $lines = $entry.Trim () -split " `n "
96+ if ($lines.Count -ge 1 ) {
97+ # Changed from 2 to 1 to catch single-line entries
98+ # Extract timestamp from first line
99+ $firstLine = $lines [0 ].Trim()
100+ if ($firstLine -match ' ^\[(.+?)\]\s*(.+?)$' ) {
101+ $timestamp = $matches [1 ]
102+ $firstMessage = $matches [2 ]
103+
104+ # Get remaining content
105+ $remainingContent = @ ()
106+ if ($lines.Count -gt 1 ) {
107+ $remainingContent = $lines [1 .. ($lines.Count - 1 )] | Where-Object - FilterScript { $_.Trim () -ne ' ' }
108+ }
109+
110+ # Combine first message with remaining content
111+ $fullMessage = @ ($firstMessage ) + $remainingContent | Where-Object - FilterScript { $_.Trim () -ne ' ' }
112+ $fullMessageText = ($fullMessage -join " `n " ).Trim()
113+
114+ # Parse structured error information if present
115+ $errorMessage = $null
116+ $positionDetail = $null
117+ $header = $null
118+
119+ if ($fullMessageText -match ' (?s)Message:\s*(.+?)\s*\nPosition:\s*(.*)' ) {
120+ $errorMessage = $matches [1 ].Trim()
121+ $positionDetail = $matches [2 ].Trim()
122+ $header = $firstMessage.Trim ()
123+ }
124+
125+ # Format the timestamp nicely
126+ $niceTime = Format-NiceTimestamp $timestamp
127+
128+ $parsedEntries += @ {
129+ Timestamp = $timestamp
130+ Message = $fullMessageText
131+ ErrorMessage = $errorMessage
132+ PositionDetail = $positionDetail
133+ Header = $header
134+ RawEntry = $entry.Trim ()
135+ NiceTime = $niceTime
136+ }
137+ }
138+ }
139+ }
140+
141+ # Reverse the order to show most recent first
142+ $reversedEntries = $parsedEntries [-1 .. - ($parsedEntries.Length )]
143+
144+ return $reversedEntries
145+ }
146+
147+ function Write-LogEntry {
148+ param ($entry )
149+
150+ # Display structured error format
151+ Show-Message - message ' Header : ' - noNewLine
152+ Show-Value - message " $ ( $entry.Header ) "
153+
154+ Show-Message - message ' Message : ' - noNewLine
155+ # Handle multi-line error messages with proper indentation (23 spaces to align with "Message :")
156+ $errorLines = $entry.ErrorMessage -split " `n "
157+ foreach ($errorLine in $errorLines ) {
158+ if ($errorLine.Trim () -ne ' ' ) {
159+ Show-Value - message " $ ( $errorLine ) "
160+ }
161+ }
162+
163+ # Display entry with nice formatting
164+ Show-Message - message ' When : ' - noNewLine
165+ Show-Value - message " $ ( $entry.NiceTime.Date ) @ $ ( $entry.NiceTime.Time ) " - noNewLine
166+ Show-Debug - message " ($ ( $entry.NiceTime.Relative ) )"
167+
168+ Show-Message - message ' Where : ' - noNewLine
169+ Show-Value - message " $ ( $entry.PositionDetail ) "
170+
171+ Show-Debug - message (' -' * 80 )
172+ }
173+
174+ function Write-LogPage {
175+ param ($entries , $startIndex , $pageSize )
176+
177+ $totalEntries = $entries.Length
178+ $endIndex = [Math ]::Min($startIndex + $pageSize - 1 , $totalEntries - 1 )
179+
180+ # Clear screen for cleaner display
181+ Clear-Host
182+
183+ # Show header
184+ Show-Info - message " `n === PVM Log Viewer ==="
185+ Show-Header - message " `n Showing entries $ ( $startIndex + 1 ) -$ ( $endIndex + 1 ) of $totalEntries (most recent first)`n "
186+
187+ # Display current page of entries
188+ $endIndex = [Math ]::Min($currentIndex + $pageSize - 1 , $totalEntries - 1 )
189+
190+ Write-DarkGray - message (' -' * 80 )
191+ for ($i = $startIndex ; $i -le $endIndex ; $i ++ ) {
192+ Write-LogEntry - entry $entries [$i ]
193+ }
194+ }
195+
196+ function Get-LogNavigation {
197+ param ($currentIndex , $pageSize , $totalEntries )
198+
199+ # $currentIndex += $pageSize
200+ # Show navigation prompt if there are more entries
201+ $isLastPage = ($currentIndex + $pageSize ) -ge $totalEntries
202+ if ($isLastPage ) {
203+ Show-Warning - message ' End of log reached. Press Left/Up arrow to go back or any other key to exit...'
204+
205+ $key = Get-ConsoleKey
206+ if ($key.Key -in @ (' LeftArrow' , ' UpArrow' )) {
207+ # Go back one page from the end
208+ return [Math ]::Max(0 , $currentIndex - $pageSize )
209+ }
210+ return $null
211+ }
212+
213+ Show-Warning - message " `n Press Left/Up arrow for previous page, Right/Down arrow, [Enter] or [Space] for next page, [Q] to quit: " - noNewLine
214+
215+ $key = Get-ConsoleKey
216+ switch ($key.Key ) {
217+ { $_ -in @ (' LeftArrow' , ' UpArrow' ) } { return [Math ]::Max(0 , $currentIndex - $pageSize ) }
218+ { $_ -in @ (' RightArrow' , ' DownArrow' , ' Enter' , ' Spacebar' ) } { return ($currentIndex + $pageSize ) }
219+ { $_ -in @ (' q' , ' Q' ) } { return $null }
220+ default { return $currentIndex }
221+ }
222+ }
223+
64224function Show-Log {
65225 param ($pageSize = $PVMConfig.env.DEFAULT_LOG_PAGE_SIZE , $term = $null )
66226
67227 try {
68- if ($pageSize -notmatch ' ^-?\d+$' ) {
69- Show-Error - message " `n Invalid page size: $pageSize "
228+ if (-not (Test-LogPageSize - pageSize $pageSize )) {
70229 return -1
71230 }
72231
73232 $pageSize = [int ]$pageSize
74- if ($pageSize -le 0 ) {
75- Show-Error - message " `n Page size must be a positive integer."
76- return -1
77- }
78233
79234 # Check if log file exists
80235 if (Test-FileNotExists - path $PVMConfig.paths.logError ) {
81236 Show-Error - message " `n Log file not found: $ ( $PVMConfig.paths.logError ) "
82237 return -1
83238 }
84239
85- # Read the entire log file
86- $logContent = Get-ContentWrapper - path $PVMConfig.paths.logError - raw
87-
88- # Split by the separator and filter out empty entries
89- $logEntries = $logContent -split ' -{26}' | Where-Object - FilterScript { $_.Trim () -ne ' ' }
90-
91- # Parse each entry into objects
92- $parsedEntries = @ ()
93- foreach ($entry in $logEntries ) {
94- if ($term -and ($entry -notmatch [regex ]::Escape($term ))) {
95- continue
96- }
97- $lines = $entry.Trim () -split " `n "
98- if ($lines.Count -ge 1 ) {
99- # Changed from 2 to 1 to catch single-line entries
100- # Extract timestamp from first line
101- $firstLine = $lines [0 ].Trim()
102- if ($firstLine -match ' ^\[(.+?)\]\s*(.+?)$' ) {
103- $timestamp = $matches [1 ]
104- $firstMessage = $matches [2 ]
105-
106- # Get remaining content
107- $remainingContent = @ ()
108- if ($lines.Count -gt 1 ) {
109- $remainingContent = $lines [1 .. ($lines.Count - 1 )] | Where-Object - FilterScript { $_.Trim () -ne ' ' }
110- }
111-
112- # Combine first message with remaining content
113- $fullMessage = @ ($firstMessage ) + $remainingContent | Where-Object - FilterScript { $_.Trim () -ne ' ' }
114- $fullMessageText = ($fullMessage -join " `n " ).Trim()
115-
116- # Parse structured error information if present
117- $errorMessage = $null
118- $positionDetail = $null
119- $header = $null
120-
121- if ($fullMessageText -match ' (?s)Message:\s*(.+?)\s*\nPosition:\s*(.*)' ) {
122- $errorMessage = $matches [1 ].Trim()
123- $positionDetail = $matches [2 ].Trim()
124- $header = $firstMessage.Trim ()
125- }
126-
127- # Format the timestamp nicely
128- $niceTime = Format-NiceTimestamp $timestamp
129-
130- $parsedEntries += @ {
131- Timestamp = $timestamp
132- Message = $fullMessageText
133- ErrorMessage = $errorMessage
134- PositionDetail = $positionDetail
135- Header = $header
136- RawEntry = $entry.Trim ()
137- NiceTime = $niceTime
138- }
139- }
140- }
141- }
142-
143- # Reverse the order to show most recent first
144- $reversedEntries = $parsedEntries [-1 .. - ($parsedEntries.Length )]
240+ $entries = @ (Get-LogEntries - path $PVMConfig.paths.logError - term $term )
145241
146- if ($reversedEntries .Count -eq 0 ) {
242+ if ($entries .Length -eq 0 ) {
147243 Show-Warning - message " `n No log entries found."
148244 return -1
149245 }
150246
151247 # Display entries with pagination
152248 $currentIndex = 0
153- $totalEntries = $reversedEntries .Count
249+ $totalEntries = $entries .Length
154250
155251 while ($currentIndex -lt $totalEntries ) {
156- # Clear screen for cleaner display
157- Clear-Host
158-
159- # Show header
160- Show-Info - message " `n === PVM Log Viewer ==="
161- Show-Header - message " `n Showing entries $ ( $currentIndex + 1 ) -$ ( [Math ]::Min($currentIndex + $PageSize , $totalEntries )) of $totalEntries (most recent first)`n "
162-
163- # Display current page of entries
164- $endIndex = [Math ]::Min($currentIndex + $PageSize - 1 , $totalEntries - 1 )
165-
166- Show-Debug - message (' -' * 80 )
167- for ($i = $currentIndex ; $i -le $endIndex ; $i ++ ) {
168- $entry = $reversedEntries [$i ]
169-
170- # Display structured error format
171- Show-Message - message ' Header : ' - noNewLine
172- Show-Value - message " $ ( $entry.Header ) "
173-
174- Show-Message - message ' Message : ' - noNewLine
175- # Handle multi-line error messages with proper indentation (23 spaces to align with "Message :")
176- $errorLines = $entry.ErrorMessage -split " `n "
177- foreach ($errorLine in $errorLines ) {
178- if ($errorLine.Trim () -ne ' ' ) {
179- Show-Value - message " $ ( $errorLine ) "
180- }
181- }
182-
183- # Display entry with nice formatting
184- Show-Message - message ' When : ' - noNewLine
185- Show-Value - message " $ ( $entry.NiceTime.Date ) @ $ ( $entry.NiceTime.Time ) " - noNewLine
186- Show-Debug - message " ($ ( $entry.NiceTime.Relative ) )"
252+ Write-LogPage - entries $entries - startIndex $currentIndex - pageSize $pageSize
187253
188- Show-Message - message ' Where : ' - noNewLine
189- Show-Value - message " $ ( $entry.PositionDetail ) "
254+ $nextIndex = Get-LogNavigation - currentIndex $currentIndex - pageSize $pageSize - totalEntries $totalEntries
190255
191- Show-Debug - message (' -' * 80 )
256+ if ($null -eq $nextIndex ) {
257+ break
192258 }
193259
194- $currentIndex += $PageSize
195- # Show navigation prompt if there are more entries
196- if ($currentIndex -lt $totalEntries ) {
197- Show-Warning - message " `n Press Left/Up arrow for previous page, Right/Down arrow, [Enter] or [Space] for next page, [Q] to quit: " - noNewLine
198-
199- $key = Get-ConsoleKey
200-
201- switch ($key.Key ) {
202- { $_ -in @ (' LeftArrow' , ' UpArrow' ) } { $currentIndex = [Math ]::Max(0 , $currentIndex - (2 * $PageSize )) }
203- { $_ -in @ (' RightArrow' , ' DownArrow' , ' Enter' , ' Spacebar' ) } { continue }
204- { $_ -in @ (' q' , ' Q' ) } { return 0 }
205- default { $currentIndex -= $PageSize }
206- }
207- } else {
208- Show-Warning - message ' End of log reached. Press Left/Up arrow to go back or any other key to exit...'
209- $key = Get-ConsoleKey
210- if ($key.Key -in @ (' LeftArrow' , ' UpArrow' )) {
211- # Go back one page from the end
212- $currentIndex = [Math ]::Max(0 , $currentIndex - (2 * $PageSize ))
213- }
214- }
260+ $currentIndex = $nextIndex
215261 }
216262
217263 Clear-Host
218264 return 0
219265 } catch {
266+ Show-Error - message " `n Failed to show log: $ ( $PVMConfig.paths.logError ) "
220267 $null = Add-LogEntry - data @ { header = " $ ( $MyInvocation.MyCommand.Name ) - Failed to show log" ; exception = $_ }
221268 return -1
222269 }
0 commit comments