首页 > 解决方案 > Powershell 提取最近 n 分钟的日志文件内容

问题描述

我正在尝试从最后 n 分钟的日志文件中提取内容,并根据提取的数据执行另一组操作。我的日志文件如下所示:

2019-01-25 02:45:55,018 [5 - -22d] INFO Server - Some information
2019-01-25 02:45:55,018 [5 - -22d] INFO Server - Some information
2019-02-25 02:45:55,018 [5 - -22d] INFO Server - Some information
2019-02-25 19:09:50,018 [5 - -22d] ERROR IOException Some Error
2019-02-25 02:45:55,018 [5 - -22d] INFO Server - Some information

我创建了一个任务计划程序,它每隔 1 分钟运行一次,并在最后 1 分钟检查日志文件中的特定错误并执行下一个操作。这里重要的是时间,我想将当前时间与日志文件时间进行比较错误发生时。我尝试过的如下:

 $data=Get-Content $log | Select-String -Pattern 'String to search error'
   foreach ($line in $data){
     $logdate = Get-Date ($line -split ',')[0] -Format 'yyyy-MM-dd HH:mm'
      Write-Output $logdate
       if($date -eq $logdate){
          Write-Output "Some action"          
       }   
   }

有没有更好的方法来达到同样的效果?由于我对 powershell 不太熟悉,社区能否提供一些启示?还尝试了各种其他 cmdlet “LastWriteTime、Get-Content、regex-等”

标签: powershelldateparsingloggingselect-string

解决方案


有其他方法可以做到这一点。

将找到的每个日期转换为 DateTime 对象并与某个参考日期进行比较。用于-like将搜索限制为仅包含指定搜索词的行。

$referenceTime  = (Get-Date '2019-02-25 19:09:00').AddMinutes(-10)
$wildcardSearch = '*ERROR*'
Get-Content -Path 'D:\SomeLog.log' | 
Where-Object { $_ -like $wildcardSearch -and (Get-Date ($_ -split ',')[0]) -gt $referenceTime }
ForEach-Object { 
    # do something here, for demo just output the 
    $_
}

或者,由于日期和时间都是可排序的格式,您不必转换为 DateTime。此演示使用正则表达式-match来比较搜索词

# the reference time in sortable string format, as are the dates in the log
$referenceTime = '{0:yyyy-MM-dd HH:mm:ss}' -f (Get-Date '2019-02-25 19:09:00').AddMinutes(-10)
# simple words like ERROR do not need escaping, but other search terms might
$regexSearch   = [regex]::Escape('ERROR') 
Get-Content -Path 'D:\SomeLog.log' | 
Where-Object { $_ -match $regexSearch -and ($_ -split ',')[0] -gt $referenceTime } |
ForEach-Object { 
    # do something here, for demo just output the 
    $_
}

或者,使用最快的方式遍历日志中的行(同样,使用正则表达式):

$referenceTime = '{0:yyyy-MM-dd HH:mm:ss}' -f (Get-Date '2019-02-25 19:09:00').AddMinutes(-10)
$regexSearch   = [regex]::Escape('ERROR') 
switch -Regex -File 'D:\SomeLog.log' {
    $regexSearch { 
        if (($_ -split ',')[0] -gt $referenceTime) { 
            # do something here, for demo just output the line
            $_ 
        }
    }
}

推荐阅读