12

I can tail one file via the following command:

Get-Content -Path C:\log1.txt -Tail 10 –Wait

How do I extend this to multiple files, I have tried the following with no luck:

Get-Content -Path C:\log1.txt,C:\log2.txt -Tail 10 –Wait

This will only pick up updates from the first file, not the second.

1
  • 3
    The -wait switch is going to block the thread. To -tail -wait multiple files at once, you're going to have to have multiple threads. Commented Feb 17, 2015 at 18:07

4 Answers 4

13

Based on @mjolinor's comment, I have come up with the following that appears to work,

Workflow My-Tail
{
    Param([string[]] $Path)

    foreach -parallel ($file in $path)
    {
        Get-Content -Path $file -Tail 1 -Wait
    }
}

My-Tail (dir C:\*.log -Include log1.txt,log2.txt)

However, this has some sort of progress bar that appears...

Sign up to request clarification or add additional context in comments.

3 Comments

You can add $ProgressPreference='SilentlyContinue' in the script to suppress the progress bar. I'm working on my own version that will also highlight and filter lines. github.com/McLeopold/TailorPosh
A workflow cannot use recursion. + CategoryInfo : ParserError: (:) [], ParseException + FullyQualifiedErrorId : RecursiveWorkflowNotSupported
This is an old answer, but workflows are deprecated in PWSH 6.x+
3

I can't speak to how efficient this is, but since I'm using PowerShell Core 7.1.3, I can't use Workflows or ForEach -Parallel, but I can use ForEach-Object -Parallel, so I tried it just to see what would happen...

Get-ChildItem -Path C:\ -Filter log*.txt |
    ForEach-Object -Parallel {
        Get-Content -Wait -Tail 10 -Path $_
    } -ThrottleLimit 30

In my case, I had 27 files I needed to monitor, so I chose a number just above that, and this seemed to work.

Just to be sure it was working, I used this, which will output the source file name before each line:

Get-ChildItem -Path C:\ -Filter log*.txt |
    ForEach-Object -Parallel {
        $file = $_;
        Get-Content -Wait -Tail 10 -Path $file |
            ForEach-Object { Write-Output "$($file.Name): ${_}" }
    } -ThrottleLimit 30

4 Comments

I made a gist based on this answer, maybe it will be useful for someone
@MonsieurMerso if you're interested, I wrote a whole blog post about it: chadbaldwin.net/2022/04/04/powershell-monitoring-log-files
Amazing, I'll mention it in my gist
great post, I referenced it in a comment in the gist.
1

Incorporating @McLeopold's comment into @Cheetah's code

function Tail (
  [Parameter(Mandatory=$true)][string[]]$Files,
  [long]$Tail = 1
) {
  workflow TailWorkflow (
    [string[]]$Files,
    [long]$Tail
  ) {
    foreach -parallel ($File in $Files) {
      Get-Content -Tail $Tail $File -Wait
    }
  }

  $ProgressPreference='SilentlyContinue'
  TailWorkflow -Files $Files -Tail $Tail
}

Comments

0

I needed tailed output across multiple files and I wanted to try do it in one line,
here's what I eventually came up with:

gci *.txt -recurse | ForEach-Object  { Write-Output "$_`n" + $(Get-Content $_ -tail 5) + "`n" }

Its takes a recursive directory listing of all files named *.txt,
writes the file path to console,
then writes the last 5 lines to console.

I didn't need to follow the tails of the files, they weren't being actively written to.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.