Monitor Text File for Additional Information

This topic contains 4 replies, has 4 voices, and was last updated by Profile photo of Don Jones Don Jones 3 years, 2 months ago.

  • Author
    Posts
  • #14694
    Profile photo of Jacob Benson
    Jacob Benson
    Participant

    I have a text log file that I need to monitor for a specific line. I know how to do this. However, when the Rule finds that line, I need information from a different line in the log file that is slightly above it. I am not sure where to begin to accomplish this. There are plenty of examples about how to parse a log file for a single line, but I am not sure how to do it so that it keeps track of all the text above the string I am looking for so I can include it an email.

    Here is an example of what the log file will look like (and it will be in this format every time). I need to monitor the log file for the line “No alert email was sent.” and then also include the line “Condition: dest_path (\\Server\Folder) does not exist or is not a directory” in the alert (and maybe some other lines if I can figure out how to do it).

    Configuration File config\test210.get at 2013-11-17, 17:12:00

    2013-11-17, 17:12:00
    Condition: dest_path (\\Server\Folder) does not exist or is not a directory

    An error log was created and stored as:
    C:/bin/../errors/1117171200004132.log

    The global configuration 'SMTPserver' property is not set or is set to an invalid value.
    No alert email was sent.
    2013-11-17, 17:12:00
    Condition: ftp communication problem. Host: rpconnect.redprairie.net

    An error log was created and stored as:
    C:/live/bin/../errors/1117171200004132.log

    The global configuration 'SMTPserver' property is not set or is set to an invalid value.
    No alert email was sent.

  • #14696
    Profile photo of Don Jones
    Don Jones
    Keymaster

    So... just as a kind of planning note, I don't think PowerShell is exceptionally well-suited to ongoing "monitoring" activities. The file I/O routines in .NET, for example, aren't the most robust (although they've improved), and PowerShell itself wasn't designed with the idea of it being a long-running monitoring tool. So there's definitely some performance/impact things to consider.

    If you look at Select-String, it can do this kind of pattern-based search. It also has a -Context switch, which allows it to return a specified number of lines before/after the "hit." The description for the parameter explains how the context is returned. That's probably where you'd want to start.

  • #14718
    Profile photo of Stein Petersen
    Stein Petersen
    Participant

    Hi Jacob.

    You could try and make the monitor remember key values from previous lines and react to the triggers you set up.


    function Parse-LogFileForErrors {
    < # #>
    [CmdLetBinding()]
    Param(
    [parameter(ValueFromPipeline=$true)]
    [ValidateScript({Test-Path $_})]
    [String]$LogFile
    )

    BEGIN {
    $matchDateString = '^\d{4}-\d{2}-\d{2}, \d{1,2}:\d{1,2}:\d{1,2}'
    $matchCondition = '^Condition: (.*)$'
    $matchTrigger = 'No alert email was sent.'
    $currentDateString = 'startup'
    $currentCondition = 'startup'
    } #end BEGIN
    PROCESS {

    $allLines = Get-Content $LogFile
    foreach ($line in $allLines) {

    switch -Regex ($line) {

    $matchDateString { Write-verbose "Found datestring"
    $currentDateString = [regex]::Match($line, $matchDateString) }
    $matchCondition { Write-Verbose "Found condition"
    $currentCondition = [regex]::Match($line, $matchCondition) }
    $matchTrigger { Write-Verbose "Found trigger, sending email [triggered: $currentDateString] [$currentCondition]"
    # call Send-MailMessage using $currentContidion as body ?
    }
    default {}

    } #end switch

    } #end foreach

    } #end PROCESS

    END {} #end END

    }

    Parse-LogFileForErrors -logFile d:\logfiles\logfile.log -Verbose

    I'm shure there is a more elegant way to do this but this one gives me two "messages" and it is easy to extend.

  • #14739
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Jacob sends his thanks for the responses – he's having some trouble posting a reply.

  • #14705
    Profile photo of Tore Groneng
    Tore Groneng
    Participant

    Hi jacob,

    You could try something like this:

    
    $str = @"
    2013-11-17, 17:12:01
    Condition: dest_path (\\Server\Folder) does not exist or is not a directory
    
    An error log was created and stored as:
    C:/bin/../errors/1117171200004132.log
    
    The global configuration 'SMTPserver' property is not set or is set to an invalid value.
    No alert email was sent.
    2013-11-17, 17:12:02
    Condition: ftp communication problem. Host: rpconnect.redprairie.net
    
    An error log was created and stored as:
    C:/live/bin/../errors/1117171200004132.log
    
    The global configuration 'SMTPserver' property is not set or is set to an invalid value.
    No alert email was sent.
    "@
    $array = $str -split [System.Environment]::NewLine
    $i = 0
    $array | foreach{$i++;if($_ -eq "No alert email was sent."){$array[$i-6-1]}}
    

    This implies that the 6th line above your "No alert email was sent." is what you are looking for. Also have to substract 1 since the array is zero based. It is not pretty, however it works 🙂

    As a side note, this does not work if you paste the code into a console window. The here-string becomes an one item array in the console, but not in ISE. Apparently the -split is unable to split on newline in the console.

    Cheers

    Tore

You must be logged in to reply to this topic.