Home > Blockchain >  Call a function when a new line is added to a log file
Call a function when a new line is added to a log file

Time:01-14

I want to tail a file and call a function when a new line is added. This is what I'm trying but it's not printing anything out which makes me think that the Get-Content isn't working.

function Check-LogLine {
    param (
        $Line
    )

    ...
}

$Global:Line = Get-Content -Path $LogPath -Tail 1 -Wait
Write-Output "Line: $Global:Line"
while ($Line -NotLike "*Stopping!") {
    $Global:Line = Get-Content -Path $LogPath -Tail 1 -Wait
    Write-Output $Global:Line
    Check-LogLine -Line $Global:Line
}

-= Edit =- It gets the last line if I remove the -Wait but it keeps getting the same last line over and over.

CodePudding user response:

You're never getting into the while loop, -Wait is blocking the thread on the first call:

$Global:Line = Get-Content -Path $LogPath -Tail 1 -Wait

You can use the pipeline instead which is meant for this, I will go and assume since you're using -Wait this will be a somewhat interactive process and you only want output to the console doesn't matter if the output goes to the Success Stream or the Information Stream. If that's the case, you can use Select-Object -First 1 to properly break the pipeline. Otherwise, if you really need the output to go the Success Stream, the solution would be very cumbersome.

Here is an example of how you can approach your code:

function Check-LogLine {
    param($Line)

    # Writing to the Information Stream
    # (this output is not passed thru the pipeline)
    Write-Host "[$([datetime]::Now.ToString('u'))] $line"
}


$tmp = New-TemporaryFile
# This job will run in the background writing to a temp file each 2 seconds
$job = Start-Job {
    $tmp = $using:tmp
    0..10 | ForEach-Object {
        Start-Sleep 2

        if($_ -ne 5) {
            "$_ ... Running!" | Add-Content $tmp.FullName
            return
        }

        "$_ ... Stopping!" | Add-Content $tmp.FullName
    }
}

try {
    Get-Content $tmp.FullName -Wait -Tail 1 | ForEach-Object {
        # The output to this function goes to the Info Stream
        Check-LogLine $_

        if($_ -like '*Stopping*') {
            Write-Host 'Stopping here...'
            $job | Stop-Job | Remove-Job

            'this output goes to Success Stream to stop this pipeline...'
        }
    } | Select-Object -First 1
}
finally {
    $tmp | Remove-Item
}
  • Related