0

I know that is not a good idea runs a script for ever but, I need to continuously tail a log file, for some days, to get the evidence of some errors.

Problem is that this log file rotates multiple times during the day and I don't know how to follow it with powershell...

I'm stuck here:

$SRV = hostname
$FPath = "C:\Logs"
$LastFile = ( Get-Item "$FPath\*" | Where-Object {$_.Name -match "Module"} | sort LastWriteTime | select -last 1 ).FullName
$LastActiveFile = (Get-FileHash -Algorithm MD5 $LastFile).Hash
$ScriptPath = "E:\Scripts\ReInvite"
$CredPath = "$ScriptPath\Creds"
$logFile = "$ScriptPath\Logs\EventsReinvites.txt"

$CallEvent = "(^[\s\S]{0,21})(.*?)(CALLID:(.*?)@10)" 

While ( (Get-FileHash -Algorithm MD5 -Path $(( Get-Item "$FPath\*" | Where-Object {$_.Name -match "Module.log"} | sort LastWriteTime | select -last 1 ).FullName)).Hash -eq $LastActiveFile ) {
    Get-Content "$LastFile" -Tail 1 -Wait | foreach {
        if ( $_ -match "REINVITE" ) {
            $SipEvent = [regex]::match($_, $CallEvent).Groups[1,4].Value
            $SipEvent | Out-File -Append $logFile
            $Subject = "RMOD -> REINVITE event triggered..."
            $MSG = "Evento 'REINVITE' ricevuto su $SRV:"
            $MSG1 = "$SipEvent"
            $MSG2 = " "
            $MSG3 = "Script Path:   \\$env:COMPUTERNAME\$($ScriptPath.replace(':', '$')) "
            $MSG4 = " "
            $body = "$MSG" + "`n`n" + "$MSG1" + "`n" + "$MSG2" + "`n`n`n" + "$MSG3" + "`n" + "$MSG4"
            Send-MailMessage -Subject $Subject -Body $body @MailArgs | Out-File "$LogDir\MailLogs.txt"
        }
    }
}

Script do the job but, as soon as log rotates, an error occour:

Get-Content : Il file 'C:\Logs\Module.2024-07-09T07-28-27-355.1.log' non è stato trovato.
In riga:1 car:1
+ Get-Content "C:\Logs\Module.2024-07-09T07-28-27-355.1.log
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ReadError: (C:\Logs\Module...28-27-355.1.log:String) [Get-Content], FileNotFoundException
    + FullyQualifiedErrorId : GetContentReaderIOError,Microsoft.PowerShell.Commands.GetContentCommand

and script exits...

Please, help me! Roberto

12
  • 1
    "an error occour" - can you add the full error message? (edit your post rather than put it in a comment).
    – mclayton
    Commented Jul 9 at 20:59
  • @mclayton, FileNotFoundException
    – ilRobby
    Commented Jul 10 at 8:00
  • $LastFile is declared first and never updated. It can be declared in the head of while, but the command there is a little different. Why? Or u redeclare it at the end of the while body
    – Dom
    Commented Jul 10 at 8:13
  • @Dom, $LastFile never change its name, when the application rotate it, also gzip it and, as a result, file's extension and "previous" file's name changes, while the new one has the same name of $LastFile variable value. That's why I've tried to match the hash of file but, I think, any operations inside the while loop are useless if file changes on disk...
    – ilRobby
    Commented Jul 10 at 8:36
  • I think that the only solution possible is another scheduled script, that checks if the "first" script is running, but, I might be wrong!
    – ilRobby
    Commented Jul 10 at 8:42

1 Answer 1

0

I wrote two scripts; first rollingLogCreator.ps1 to simulate the behavior of creating log files making entries, than changing their names (making an archive out of them) and creating the next log file with a different name:

param($interval=1,$intervalRotations=10,$totalUpdateLoops=30)
$ScriptPath = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
$pathtoLogs=$ScriptPath +"\logs"
if(-not(test-path -path $pathtoLogs)){write-host "not $ScriptPath";New-Item -Path $ScriptPath -Name "logs" -ItemType Directory}
$FileFriendlyDate= (Get-Date -Format FileDateTime).toString()
$oldpath=$scriptpath+"\logs\Module"+ $FileFriendlyDate+".log"
start-transcript -path $oldpath
for($i=0;$i -le $totalUpdateLoops; $i++){
    "$((Get-Date -Format FileDateTime).toString()) $making porgress with giving update for the $iTh time"
    if(($i % 6) -eq 0){write-host "inportant reinvite event no $i"}
    start-sleep $interval
    if((($i % $intervalRotations) -eq 0) -and ($i -gt 0)){
        stop-transcript
        Rename-Item -Path $oldpath -NewName "ModuleZip$FileFriendlyDate.txt"
        $FileFriendlyDate= (Get-Date -Format FileDateTime).toString()
        $newpath=$scriptpath+"\logs\Module"+ $FileFriendlyDate+".log"
        start-transcript -path $oldpath
    }
}

And secondly rollingLogFollower.ps1 to observe the newest file in the given directory and react to the keyword "REINVITE":

  $LastFile = ( Get-ChildItem "$FPath\*" | Where-Object {$_.Name -like "Module*.log"} | sort LastWriteTime | select -last 1 ).FullName
     
  Get-Content $LastFile -Wait -Last 0 |
  where-Object { $_ -match 'REINVITE' } |
  ForEach-Object {write-host "match"}

I was shocked by the simplicity of it, but it works: When the name of the log is changing "Get-Content -wait" seems to realise it on its own and update $lastfile. The only problem i ran into was starting the follower before starting the creator at the beginning. Then it was like the follower was already asleep not realising new files been created / updates are made. but after stopping it with cntrl+c and starting it over found the track and once it did i could keep it running and wait as long as i want to start the creator again and generate more logs. It wont loose track once its on to it, like a bloodhound.Please try for your self: You can adjust the parameter of your tests: $interval sets the time between each log entry,$intervalRotations is the number of entries till the script changes to the next logfile and $totalUpdateLoops will set total number of loops for your test. u can overload the default values declared at the beginning in "param()" by calling the script (drag & drop it into your powershell window) and append your numbers at the end so it looks like this eg: "path\to\this\script\rollingLogCreator.ps1 2 4 80" After starting the creator start the follower in a different window. Once comfortable with this you can change the path of the follower to the real path.

Not the answer you're looking for? Browse other questions tagged or ask your own question.