Powershell通过日志时间戳发送特定于错误的电子邮件

时间:2015-09-17 15:27:46

标签: powershell logging alert

$log = "C:\bobloblawslawblog.log"
Get-Content $log |
? {$_.Modified -le $(Get-Date).AddHours(-4)} |
Select-String "TCP" -Context 1 |
% { @($_.Context.PreContext) + @($_.Line)}
{
$Workstation = hostname
$emailSmtpServer = "mail.server"
$emailFrom = "Error CODE 1234@$Workstation.com"
$emailTo = "my.name@my.company.com"
$emailSubject = "$Workstation Error CODE 1234"
$emailBody = "$Workstation experiencing Error Code 1234"
Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Credential $credentials -Body $emailBody -SmtpServer $emailSmtpServer
$credentials= New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
}

我似乎无法从过去的4小时内获取此错误。该脚本会抓取所有匹配的代码并将它们一起发送。

日志文件中时间戳的格式为:

[2015-09-01 03:12:34,774] INFO com.server.mobilize.jte.service.listener.DesktopClientTransferListener(147) exception (Transport Protocol Seeker)- 218362: a warning or retriable exception has occurred Transfer warning: Error connecting to TCP Server-A/127.0.0.1:49221 relayed via Sever-B/External-IP:49221: Connection lost on tcp port read 

我不知道最后3个号码' 975'表明。它不是一个pid。

我想要做的是让脚本抓取.log文件 - 返回过去4小时的匹配并发送提醒。

理想情况下,我希望电子邮件正文包含日志中的实际错误。

1 个答案:

答案 0 :(得分:0)

就像我在评论中说的那样,您正在尝试访问管道中不存在的属性。 Get-Content返回一个字符串数组。请记住,那些字符串确实具有像linenumber这样的特殊属性,没有什么神奇的方法可以解释开头的日期。这取决于我们。

Get-Content $log | ForEach-Object{
    # Extract the date
    $date = $null # Assume null

    # Match the data that occurs after the bracket and before the comma. This can only be at the beginning of the line.  
    If($_ -match "^\[(.*?),"){
        $date= [datetime]$matches[1]
    }

    # Build a new object as pass it along the pipe
    New-Object -TypeName psobject -Property @{
        Modified = $date
        Line = $_
    }
} 

有很多方法可以做到这一点,但我选择创建一个新对象,我们为它提供一个修改过的属性。我们使用正则表达式从行的开头提取日期并将其转换为[datetime],以便您现在可以执行日期计算。

假设您的其他逻辑符合您的要求,您只需在我上面的代码段中的最后一个}之后添加它。

更好一点

制作另一个对象似乎浪费资源,所以我在Where中使用相同的逻辑。我还添加了代码的Select-String部分。我做了一些改变。

$results = Get-Content $log | Where-Object{
    # Match the data that occurs after the bracket and before the comma. This can only be at the beginning of the line.  
    $date = $null
    If($_ -match "^\[(.*?),"){$date = [datetime]$matches[1]}
    $date -gt (Get-Date).AddHours(-4)
} | Select-String "tcp" -Context 1 | ForEach-Object{
    "{0}`r`n{1}`r`n{2}" -f ($_.Context.Precontext -join "`r`n"), $_.line, ($_.context.postcontext -join "`r`n")
}

现在结果就是这样。所以你会在那里看到过去4个小时内发生的所有条目,这些条目在某个地方有一个字符串“TCP”。它还将包括比赛前后的线路。 $results有可能成为一个数组,因此您需要在电子邮件中对此进行说明。一个简单的$results -join "`r`n"会做到这一点。