首页 > 解决方案 > 实时监控windows日志文件中的错误

问题描述

我的服务器上部署了多个 Windows 服务。我想实现一个 PowerShell 脚本,它可以对这些服务的日志进行实时监控。它必须在日志文件中查找关键字(例如错误、异常),一旦出现任何错误,脚本应该向预先配置的电子邮件地址发送通知。我在网上进行了基本搜索,可以找到一些可以做到这一点的免费软件应用程序,但我并不热衷于在服务器上安装这些应用程序。如果这可以通过基本的 PowerShell 脚本或批处理脚本来完成,并且可以在后台运行,那就太好了。

我找到了可以实时观看文件的 Get-Content 和 Type -wait 命令

Get-Content error.log -wait | where { $_ -match "ERROR" }

如果您可以添加一些可能有帮助的网络链接,我将非常感谢您在电子邮件通知部分提供的任何帮助。

有点复杂的是日志文件不会是固定的,每天都会创建一个新的日志文件,脚本应该根据文件名或创建日期等自动识别最新的文件。

文件名格式为 8_05_2021.txt、9_05_2021.txt、10_05_2021.txt

标签: windowspowershellmonitoring

解决方案


如果我的逻辑是正确的,我认为这应该可行,这个脚本将无限期地运行。

对于在 PowerShell 中发送邮件,您有两个我知道的选项,一个是使用为此设计的 cmdlet:Send-MailMessage

但是,重要的是要注意:

警告
Send-MailMessage cmdlet 已过时。此 cmdlet 不保证与 SMTP 服务器的安全连接。虽然 PowerShell 中没有立即可用的替代品,但我们建议您不要使用 Send-MailMessage。有关详细信息,请参阅平台兼容性说明 DE0005。

您可以在此处使用找到第二个选项Net.Mail.MailMessage

现在对于脚本的代码,您可以使用以下内容:

# Define the full path of your logs folder
$logsFolder = 'fullPath\to\logsFolder'

# Function for monitoring and retrieving the newest log file Full Path
function monitorPath($LogPath){
    (Get-ChildItem "$LogPath\*.txt" |
    Sort-Object -Descending CreationTime |
    Select-Object -First 1).FullName
}

# Get the newest log file
$logFilePath = monitorPath -LogPath $logsFolder

while($true)
{
    # If we don't have today's date stored
    # or the update trigger is True
    if($updateDate -or -not $today)
    {
        $today = [datetime]::Today
        $updateDate = $false
    }
    
    if($today -lt [datetime]::Today)
    {
        # Trigger our previous condition
        $updateDate = $true

        # Get the new log file for this day
        $logFilePath = monitorPath -LogPath $logsFolder
    }

    if((Get-Content $logFilePath -Raw) -match 'Error')
    {
        # Send mail message goes here
    }

    Start-Sleep -Seconds 60
}

重要的是要注意,如果日志文件中有错误,这将每分钟向您的收件箱发送垃圾邮件,因此在此块中添加新条件可能是个好主意:

if((Get-Content $logFilePath -Raw) -match 'Error')
{ .... }

例如这样的:

if((Get-Content $logFilePath -Raw) -match 'Error' -and -not $emailSentThisDay)
{
    # Send mail message goes here

    # Here you set this bool to True so you don't get spammed :D
    $emailSentThisDay = $true
}

如果这是您将考虑的事情,那么您将需要$emailSentThisDay每天重置布尔值,以便:

if($today -lt [datetime]::Today)
{
    # Trigger our previous condition
    $updateDate = $true

    # Reset the antispam bool if this is a new day
    $emailSentThisDay = $false
    
    # Get the new log file for this day
    $logFilePath = monitorPath -LogPath $logsFolder
}

推荐阅读