regex - Powershell log tailer issues -
i have written log tailer powershell, tailer loads in xml file contains configuration information regarding when report on word match in log tail (basically if patterns occur x amount of times in tail).
at moment tailer not returning matches many of lines contain matches.
for example retrieving log file many info lines, if check word info nothing detected, if work shutdown returns matches (the line shutdown contains info on line).
the strange thing using same log file , same powershell script seems produce accurate results on own machine behaves strangely on server.
i suspect might issue version of powershell running on server, hoping here might know of issues can come different versions. have noticed when print out number of matches, if nothing found output blank, perhaps should 0 , causing weird issue trigger?
function main() { #### global settings $debugpreference = "continue" $servername = $env:computername $scriptpath = split-path $script:myinvocation.mycommand.path $logconfigpath = "$scriptpath/config.xml" #### variables relating log file #contains log path , log file mask $logpaths = @() $logfilemasks = @() # total number of lines grabbed end of log file evaluation $numlinestotail = 1000 # key value pair strings match , max count of matches before considered issue $keywords = @() $maxcounts = @() #### variables relating email settings $smtpserver = "mail server" $emailsubject = "$servername log report" $toemailaddress = "email accounts" $fromemailaddress = "" # initial content want in email body should go here (e.g. name of server on) $htmlbodycontent = "<p><h3>server $servername : </h3></p><p>items appear in red have exceeded match threshold , should investigated.<br/>tail lines: $numlinestotail</p>" #### function calls loadlogtailerconfig $logconfigpath ([ref]$logpaths) ([ref]$logfilemasks) ([ref]$keywords) ([ref]$maxcounts) ($i = 0; $i -lt $logpaths.count; $i++) { $tail = getlogtail $numlinestotail $logpaths[$i] $logfilemasks[$i] $tailissuetable = checkforkeywords $tail $keywords[$i] $maxcounts[$i] if ($tailissuetable -ne "") { $htmlbodycontent += "<br/>logs scanned: " + (getlatestlogfilefullname $logpaths[$i] $logfilemasks[$i]) + "<br/><br/>" + $tailissuetable sendissueemail $smtpserver $emailsubject $toemailaddress $ccemailaddress $fromemailaddress $htmlbodycontent } } } # loads in configuration data utility use function loadlogtailerconfig($logconfigpath, [ref]$logpaths, [ref]$logfilemasks, [ref]$keywords, [ref]$maxcounts) { write-debug "loading config file data $logconfigpath" [xml]$configdata = get-content $logconfigpath foreach ($log in $configdata.logs.log) { $logpaths.value += $log.filepath $logfilemasks.value += $log.filemask $kwp = @() $kwc = @() foreach ($keywordset in $log.keywords.keyword) { $kwp += $keywordset.pattern $kwc += $keywordset.maxmatches } $keywords.value += @(,$kwp) $maxcounts.value += @(,$kwc) } } # gets string containing last x lines of recent log file function getlogtail($numlinestotail, $logpath, $logfilemask) { $logfile = getlatestlogfilefullname $logpath $logfilemask #get-childitem $logpath -filter $logfilemask | sort lastwritetime | select -last 1 write-debug "getting $numlinestotail line tail of $logfile" $tail = get-content "$logfile" | select -last $numlinestotail return $tail } function getlatestlogfilefullname($logpath, $logfilemask) { $logfile = get-childitem $logpath -filter $logfilemask | sort lastwritetime | select -last 1 return "$logpath$logfile" } # returns body text email containing details on keywords in log file , frequency function checkforkeywords($tail, $keywords, $maxcounts) { $issuesfound = 0 $htmlbodycontent += "<table><tr><th style=""text-align : left;"">keyword</th><th>max count value</th><th>count total<th></tr>" ($i = 0; $i -lt $keywords.count; $i++) { $keywordcount = ($tail | select-string $keywords[$i] -allmatches).matches.count write-debug (("match count {0} : {1}" -f $keywords[$i], $keywordcount)) if ($keywordcount -gt $maxcounts[$i]) { # style red if count threshold has been exceeded $htmlbodycontent += "<tr style=""color : red;""><td>" + $keywords[$i] + "</td><td>" + $maxcounts[$i] + "</td><td>" + $keywordcount + "</td></tr>" $issuesfound = 1 } else { # style green if count threshold has not been exceeded $htmlbodycontent += "<tr style=""color : green;""><td>" + $keywords[$i] + "</td><td>" + $maxcounts[$i] + "</td><td>" + $keywordcount + "</td></tr>" } } $htmlbodycontent += "</table>" if ($issuesfound -eq 1) { return $htmlbodycontent } return "" } # sends out email specified email address function sendissueemail($smtpserver, $subject, $toaddress, $ccaddress, $fromaddress, $bodycontent) { write-debug "sending email subject: $subject, to: $toaddress, via smtp ($smtpserver)" send-mailmessage -smtpserver $smtpserver -subject $subject -to $toaddress -from $fromaddress -bodyashtml $bodycontent } cls main
and xml config example:
<logs> <log> <filepath>c:/some/path</filepath> <filemask>log.*</filemask> <keywords> <keyword> <pattern>nullreferenceexception</pattern> <maxmatches>10</maxmatches> </keyword> <keyword> <pattern>exception</pattern> <maxmatches>10</maxmatches> </keyword> </keywords> </log> <log> <filepath>c:/some/path</filepath> <filemask>test.*</filemask> <keywords> <keyword> <pattern>nullreferenceexception</pattern> <maxmatches>100</maxmatches> </keyword> </keywords> </log> </logs>
edit : server having issues running powershell v 1.0, test servers running same version fine...
your function getlatestlogfilefullname 1 problem. can , generate invalid paths.
function getlatestlogfilefullname($logpath, $logfilemask) { $logfile = get-childitem $logpath -filter $logfilemask | sort lastwritetime | select -last 1 return "$logpath$logfile" }
use instead:
return $logfile.fullname
and should check cases there no valid log file:
if ($logfile) { return $logfile.fullname } else { return $null }
the second problem select-string usage.
$keywordcount = ($tail | select-string $keywords[$i] -allmatches).matches.count
in powershell v1 select-string not have -allmatches parameter.
ps> get-help select-string name select-string synopsis identifies patterns in strings. syntax select-string [-pattern] <string[]> -inputobject <psobject>[-include <string[]>] [-exclude <string[]>] [-simplematch] [-casesensitive] [-quiet] [-list] [<commonparameters>] select-string [-pattern] <string[]> [-path] <string[]> [-include<string[]>] [-exclude <string[]>] [-simplematch] [-casesensitive] [-quiet] [-list] [<commonparameters>]
check powershell versions on servers using $psversiontable variable. not rely on version displayed in title bar!
if variable not exist have version 1.
Comments
Post a Comment