powershell - Er der en måde at lave et link/symlink/genvej til den nyeste fil i Windows? Hold tailing den nyeste logfil

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg søgte højt og lavt, fundet hvordan man gør det i * nix, men intet om Windows.


Første sted jeg har set dette var Tomcat s catalina.out, og nu spekulerede jeg på, hvordan man gør en lignende ting på Windows: overvejer en mappe, hvor logfiler oprettes, hvordan man laver en fil, der læser de seneste point/point log oprettet?


Jeg tænker på en Powershell løsning kan være mulig, men jeg kan ærligt tænke eller finde nogen måde at gøre det.


(rediger) Du downvoting kunne i det mindste efterlade en kommentar for at fortælle mig, hvad gjorde jeg forkert, eller hvordan kan jeg forbedre dette spørgsmål?


(rediger) Ideen her er at skabe en symlink, der peger på den nyeste logfil i en mappe, så et program kan altid overvåge samme fil, uanset om den nyeste fil ændrer sit navn - som tail -f catalina.out læser altid den nyeste katalina logfil.


Den eneste vej ud jeg kan se, og at jeg ville undgå, ville være at skrive et powerhell script, der ville overvåge en mappe (https://superuser.com/questions/226828/how-to-monitor-a-folder- and-trigger-a-command-line-action-når-en-fil-er-oprettet) og dynamisk oprette en symlink til den seneste fil fundet (https://stackoverflow.com/a/11211005/1985023), så sæt det som en tjeneste, så det ville altid køre på baggrunden. [7]

Bedste reference


I stedet for at kigge efter en dynamisk selvopdaterende symlink (som ville være ret besværligt at implementere - se de nyttige tip fra BACON i kommentarerne i spørgsmålet), kan du gøre dette arbejde som en selvstændig funktion/script med hjælp fra PowerShell baggrundsopgaver :



  • Kør i en loop , der regelmæssigt får de nyeste logfillinjer fra et baggrundsjob, der svarer til Unix tail -f via Get-Content -Wait -Tail 10.

  • Hvis en ny logfil er fundet, skal du afslutte det foregående baggrundsarbejde og starte en for den nye logfil.



Bemærk, at dette afhænger af periodisk afstemning af baggrundsjobbet, der haler loggen. Koden nedenfor giver dig mulighed for at justere pollingintervallet.

Bemærk at Get-Content -Wait selv poller målfilen for ændringer hvert sekund.


Her er koden; Kør $VerbosePreference = 'Continue' for at se, hvad der foregår indenfor sløjfen:




$dir = 'C:path	ologs' # the log-file directory
$logFilePattern = '*.log' # wildcard pattern matching log files
$sleepIntervalMs = 1000  # how many msec. to sleep between getting new lines from the background job

Write-Host -ForegroundColor Green "Tailing the latest log(s) in $dir...`nPress any key to quit."
$currJob = $currLog = $null
while ($true) {

  # If the user pressed a key, clean up and exit.
  if ([console]::KeyAvailable) {
    $null = [console]::ReadKey($True) # consume the key - it will still have printed, though
    if ($currJob) { Remove-Job -Job $currJob -Force }
    break
  }

  # Get the latest lines from the current log from the background job.
  if ($currJob) {
    Write-Verbose "Checking for new lines in $newLog..."
    Receive-Job -Job $currJob
    Start-Sleep -Milliseconds $sleepIntervalMs  # sleep a little
  }

  # Determine the first / newest log.
  $newLog = Get-ChildItem -LiteralPath $dir -Filter $logFilePattern | Sort-Object CreationTimeUtc -Descending | Select-Object -First 1
  if ($newLog.FullName -ne $currLog.FullName) { # new log file found.

    Write-Verbose "(New) log file found: $newLog"

    if ($currJob) {
        Write-Verbose "Terminating background job for previous log ($currLog)."
        Remove-Job -Job $currJob -Force
        # When a *new* log was just started, we show *all* lines (and keep listening for more).
        $tailArg = @{} 
    } else {
        # When we first start monitoring, we start with the *last 10* lines
        # of the current log (and keep listening for more).
        $tailArg = @{ Tail = 10 } # On first
    }

    $currLog = $newLog

    Write-Verbose "Starting background job for $currLog..."
    # Start the background job for the new log.
    $currJob = Start-Job { Get-Content -Wait @using:tailArg -LiteralPath $using:newLog.FullName }

  }

}
Write-Host -ForegroundColor Green "Terminated."