Powershell日志报告问题

时间:2015-03-17 00:51:07

标签: regex xml powershell

我已经使用Powershell编写了一个日志记录器,该文件包加载在一个xml文件中,该文件包含有关何时在日志尾部报告单词匹配的配置信息(基本上如果某些模式在尾部出现X次)。

目前,该帖子没有为包含匹配项的许多行返回匹配项。

例如,我们正在检索具有许多INFO行的日志文件,如果我检查单词INFO没有检测到任何内容,但是如果我查找工作关闭它返回匹配(带有shutdown的行也包含行上的INFO) 。

真正奇怪的是,使用相同的日志文件和相同的Powershell脚本似乎可以在我自己的机器上生成完全准确的结果,但在服务器上表现得很奇怪。

我怀疑这可能是服务器上运行的Powershell版本的一个问题,所以我希望这里有人可能知道可以提出不同版本的问题。我还注意到,当我打印出匹配的数量时,如果没有找到任何结果,输出是空白的,也许这应该是0并导致一些奇怪的问题被触发?

function Main()
{
    #### GLOBAL SETTINGS

    $DebugPreference = "Continue"
    $serverName = $env:COMPUTERNAME
    $scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
    $logConfigPath = "$scriptPath/config.xml"



    #### VARIABLES RELATING TO THE LOG FILE

    #contains the log path and log file mask
    $logPaths = @()
    $logFileMasks = @()

    # the total number of lines grabbed from the end of the log file for evaluation
    $numLinesToTail = 1000

    # key value pair for the strings to match and the max count of matches before they are considered an issue
    $keywords = @()
    $maxCounts = @()



    #### VARIABLES RELATING TO THE EMAIL SETTINGS

    $smtpServer = "mail server"
    $emailSubject = "$serverName log report"
    $toEmailAddress = "email accounts"
    $fromEmailAddress = ""

    # any initial content you want in the email body should go here (e.g. the name of the server that this is on)
    $htmlBodyContent = "<p><h3>SERVER $serverName : </h3></p><p>Items that appear in red have exceeded their match threshold and should be investigated.<br/>Tail Lines: $numLinesToTail</p>"



    #### FUNCTION CALLS

    LoadLogTailerConfig $logConfigPath ([ref]$logPaths) ([ref]$logFileMasks) ([ref]$keywords) ([ref]$maxCounts)

    for ($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 for the utility to use
function LoadLogTailerConfig($logConfigPath, [ref]$logPaths, [ref]$logFileMasks, [ref]$keywords, [ref]$maxCounts)
{
    Write-Debug "Loading config file data from $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 a string containing the last X lines of the most 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 for email containing details on keywords in the log file and their 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>"

    for ($i = 0; $i -lt $keywords.Count; $i++)
    {
        $keywordCount = ($tail | Select-String $keywords[$i] -AllMatches).Matches.Count

        Write-Debug (("Match count for {0} : {1}" -f $keywords[$i], $keywordCount))

        if ($keywordCount -gt $maxCounts[$i])
        {
            # style red if the 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 the 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 an email to the specified email address
function SendIssueEmail($smtpServer, $subject, $toAddress, $ccAddress, $fromAddress, $bodyContent)
{
    Write-Debug "Sending email with subject: $subject, To: $toAddress, via SMTP ($smtpServer)"

    Send-MailMessage -SmtpServer $smtpServer -Subject $subject -To $toAddress -From $fromAddress -BodyAsHtml $bodyContent
}

cls
Main

一个XML配置示例:

<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>
编辑:遇到问题的服务器正在运行Powershell V 1.0,但测试服务器也运行相同的版本完全正常......

1 个答案:

答案 0 :(得分:1)

您的函数GetLatestLogFileFullName是一个问题。它可以并且将生成无效路径。

function GetLatestLogFileFullName($logPath, $logFileMask)
{
    $logFile = Get-ChildItem $logPath -Filter $logFileMask | sort LastWriteTime | select -Last 1 
    return "$logPath$logFile"
}

请改用:

return $logfile.FullName

您还应该检查没有有效日志文件的情况:

if ($logfile) {
    return $logfile.FullName
} else {
    return $null
}

第二个问题是你的Select-String用法。

$keywordCount = ($tail | Select-String $keywords[$i] -AllMatches).Matches.Count

在PowerShell v1中,Select-String没有-AllMatches参数。

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>]

使用$ PSVersionTable变量检查服务器上的PowerShell版本。不要依赖标题栏中显示的版本!

PowerShell Version Confusion

如果变量不存在,则您拥有版本1。