Public/Watch-LogFile.ps1
|
function Watch-LogFile { <# .SYNOPSIS Tail log files with optional filtering. .DESCRIPTION Watch a log file in real-time, similar to Unix 'tail -f'. Supports filtering by pattern and showing last N lines. .PARAMETER Path Path to the log file. .PARAMETER Filter Filter pattern (regex) to highlight or filter lines. .PARAMETER Last Show only the last N lines initially. .PARAMETER NoFollow Don't follow the file, just show the last lines. .PARAMETER FilterOnly Only show lines matching the filter. .EXAMPLE Watch-LogFile .\app.log tail .\app.log -Filter "error" #> [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = $true)] [string]$Path, [Parameter(Position = 1)] [string]$Filter, [int]$Last = 20, [switch]$NoFollow, [switch]$FilterOnly ) $resolvedPath = Resolve-Path $Path -ErrorAction SilentlyContinue if (-not $resolvedPath) { Write-Host "File not found: $Path" -ForegroundColor Red return } $Path = $resolvedPath.Path function Write-LogLine { param( [string]$Line, [string]$Pattern ) if ($FilterOnly -and $Pattern -and $Line -notmatch $Pattern) { return } $color = 'White' if ($Line -match '\b(ERROR|FATAL|CRITICAL|EXCEPTION)\b') { $color = 'Red' } elseif ($Line -match '\b(WARN|WARNING)\b') { $color = 'Yellow' } elseif ($Line -match '\b(INFO)\b') { $color = 'Cyan' } elseif ($Line -match '\b(DEBUG|TRACE)\b') { $color = 'DarkGray' } elseif ($Line -match '\b(SUCCESS|OK)\b') { $color = 'Green' } if ($Pattern -and $Line -match $Pattern) { $parts = $Line -split "($Pattern)" foreach ($part in $parts) { if ($part -match $Pattern) { Write-Host $part -NoNewline -ForegroundColor Black -BackgroundColor Yellow } else { Write-Host $part -NoNewline -ForegroundColor $color } } Write-Host "" } else { Write-Host $Line -ForegroundColor $color } } Write-Host "" Write-Host "Tailing: " -NoNewline -ForegroundColor Cyan Write-Host $Path -ForegroundColor Yellow if ($Filter) { Write-Host "Filter: " -NoNewline -ForegroundColor Cyan Write-Host $Filter -ForegroundColor Yellow } Write-Host ("-" * 60) -ForegroundColor DarkGray Write-Host "" $lines = Get-Content $Path -Tail $Last -ErrorAction SilentlyContinue foreach ($line in $lines) { Write-LogLine -Line $line -Pattern $Filter } if (-not $NoFollow) { Write-Host "" Write-Host "--- Watching for changes (Ctrl+C to stop) ---" -ForegroundColor DarkGray Write-Host "" try { Get-Content $Path -Wait -Tail 0 | ForEach-Object { Write-LogLine -Line $_ -Pattern $Filter } } catch { Write-Host "" Write-Host "Stopped watching." -ForegroundColor Gray } } } |