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.
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.
$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.