Monitor Text File for Additional Information

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

  • Author
    Posts
  • #14694

    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

    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

    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

    Don Jones
    Keymaster

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

  • #14705

    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.