Powershell 3. Tailing a log file does not update output to the console as the log file updates

StackOverflow https://stackoverflow.com/questions/22261046

  •  11-06-2023
  •  | 
  •  

Question

I want to tail a log file on Windows as this log file is updating. I am using PowerShell version 3.0. Other people say to do:

Get-Content C:\some\server\logs\query.log -Tail 4 -Wait

However, when I send new queries to the server (and hence update the query.log) PowerShell hangs at the terminal and does not spit out any new 'tailing' to the terminal. The only way to get powershell to 'spit out' the rest of the tail in the query.log is to manually open my query.log in notepad++, and/or close the query.log from my text editor, only then does Powershell print out the rest of the log file to the terminal.

I would like to not have to open and close the log file for the powershell script to update the terminal.

many thanks

Was it helpful?

Solution

thanks for the 'baretail' recommendation. AFAIK, I was unable to stream the text from baretail into a variable in powershell, so that I could do further processing on the log data.

So, I wrote a tail function myself. Feel free to use it as is. There are some things to be aware of with this script: 1. I used 'Get-Content' (so for very long log files, you may want to optimize this command) 2. I don't use a 'sleep' function in my while loop, so this function is very CPU intensive. 3. I used 'Get-Content' as opposed to 'io FileStream' because io FileStream was unable to open log files that are 'locked' by other processes (such as a server writing to the log file). Although I think FileStream would have been more efficient since I would have been able to 'seek' byte blocks from the file instead of 'Get-Content' which loads the entire file? 4. This script is capable of tailing log files that occasionally DECREASE in size (for example when the server moves a log file that is too big from one location to another and creates a new log file with the same name in the place of the old one). Though if this happens, it's possible the very last log in the log file won't be captured when a new log is created. $pathToLogFile = 'C:\path\to\logs\query.log'

Function getFileSize($path)
{
  return (Get-Item $path).length
}

Function Tail($pathToLogFile, $fileSizeAtLastTail, $currentFileSize)
{ 
  if($currentFileSize -ne $fileSizeAtLastTail)
  {
    if ($currentFileSize -gt $fileSizeAtLastTail)
    { #Take just what is new since the last tail
      $numberOfNewBytes = $currentFileSize-$fileSizeAtLastTail
      $buf              = new-object byte[] $numberOfNewBytes
      $fs               = Get-Content $pathToLogFile -encoding Byte
      $byteTail         = $fs[$fileSizeAtLastTail .. $currentFileSize]
    }
    else
    { #Take the whole file (an new file.log was created)
      $numberOfNewBytes = $currentFileSize
      $buf              = new-object byte[] $numberOfNewBytes
      $fs               = Get-Content $pathToLogFile -encoding Byte
      $byteTail         = $fs[0 .. $currentFileSize]
    }
    #Turn bytes into a string
    $enc  = [System.Text.Encoding]::ASCII
    $tail = $enc.GetString($byteTail)
    return $tail
  }
  else
  {
    return ""
  }
}

while(1)
{
  $fileSizeAtLastTail = $currentFileSize
  $currentFileSize    = getFileSize $pathToLogFile
  $tail               = Tail $pathToLogFile $fileSizeAtLastTail $currentFileSize 
  if($tail)
  {
    $tail
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top