Powershell извлекает содержимое файла журнала за последние n минут - PullRequest
0 голосов
/ 25 мая 2020

Я пытаюсь извлечь содержимое из файла журнала за последние 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 минуту, проверяет файл журнала на наличие указанной c ошибки за последнюю 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? Также пробовал различные другие командлеты «LastWriteTime, Get-Content, regex-, et c»

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Существуют альтернативные способы сделать это.

Преобразовать каждую найденную дату в объект 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
            $_ 
        }
    }
}
0 голосов
/ 25 мая 2020

Убедитесь, что вы запускаете сценарий PowerShell от имени администратора и запускаете его перед первым запуском службы.

И следующий код будет продолжать перезапуск службы, когда это "ERROR IOException"

Get-Content -Tail 0 -Path $log -Wait | % {
    if($_ -like "*ERROR IOException*"){ # use * as wildcards
        write-host $_ -ForegroundColor Red
        write-host Restart your service
        Restart-Service -Name "__NAME OF YOUR SERVICE__" -Force
    }
}
...