none
Workflow Select-String RRS feed

  • Вопрос

  • Добрый день

    Есть куча .log файлов

    Пытаюсь оптимизировать парсинг логов

    Если делаю так

    $array = Get-Chileditem -path $path -include $include -Recurse | Select -ExpandProperty FullName
    
    Select-String -path $array -pattern $pattern
    

    Работает гораздо быстрее чем workflow

    Workflow owaparsing
        { 
        $input_logs = 'C:\'
        $Include = '*.log'
        $iterationA = 'C:\outfile.txt'
        $Pattern = "/owa/ev.owa"
        $Reports = Get-ChildItem -Path $input_logs -Include "$Include" -Recurse | select -ExpandProperty Fullname
        $array = @()
        ForEach -Parallel ( $Report in $Reports )     
            {         
             $WORKFLOW:array +=  Select-String -Path $Report -Pattern $Pattern
            }
            $array | Out-File $iterationA -Append 
        } 

    Я хочу оптимизировать поиск нужных значений в большом количестве логов, но почему то в параллель работает медленнее значительно чем просто Select-string


    4 апреля 2017 г. 6:27

Ответы

  • С LogParser явно быстрее код отработает. Да и в одну строку.

    LogParser.exe -i:iisw3c "Select * from C:\*.log where cs-uri-stem LIKE '%/OWA/ev.owa%'" -o:csv | convertfrom-csv | 
    	Group cs-username | ? {$_.Name} | Select Name,@{n="LastLogon";e={ $_.Group | % {([datetime]"$($_.Date) $($_.Time)").AddHours(3)} | Sort | Select  -last 1 }}

    или

    LogParser.exe -i:iisw3c "select cs-username,MAX(date) AS Date,MAX(time) AS Time from C:\*.log where cs-uri-stem LIKE '%/OWA/ev.owa%' and cs-username Like '%' GROUP-o:csv -stats:OFF | convertfrom-csv | sort cs-username

    Если обойтись без LogParser:

    $h = "date","time","s-ip","cs-method","cs-uri-stem","cs-uri-query","s-port","cs-username","c-ip","cs(User-Agent)","cs(Referer)","sc-status","sc-substatus","sc-win32-status","time-taken"

    Select-String *.log -Pattern "/owa/ev.owa" | % {$_.line} | ConvertFrom-Csv -Header $h -Delimiter " " | Group cs-username | Select Name,@{n="LastLogon";e={ $_.Group | Sort {[datetime]"$($_.Date) $($_.Time)"}| Select -last 1 | Foreach {"$($_.Date) $($_.Time)"}}}





    • Изменено KazunEditor 4 апреля 2017 г. 10:42
    • Помечено в качестве ответа SharpQ 4 апреля 2017 г. 12:05
    4 апреля 2017 г. 10:05
    Отвечающий

Все ответы

  • Оптимизации с Workflow не будет, от того что вы создадите кучу запросов, только замедлит любое действие работы с диском. $WORKFLOW:array += - очень медленная операция.

    Все упирается в  I/O диска и большой поток очередей, точно не улучшает. Для парсинга логов Exchange или IIS, лучше использовать Log Parser 2.2 .

    LogParser.exe -i:iisw3c "Select * into C:\outfile.txt From C:\*.log Where cs-uri-stem LIKE '%/OWA/ev.owa%'" -o:csv

    4 апреля 2017 г. 7:06
    Отвечающий
  • Спасибо за ответ.

    у меня 3 ступени отработки

    1 я получаю уникальный список пользователей из лога

    2 я получаю последнюю дату у эту пользователя

    3 создаю массив где Имя и последний вход

    Мне к сожалению просто парсинг и нахождение строк не подоходит

    Сейчас, я это делаю таким методом который осилил

    #Interation A
    #Export all line with $Pattern from all logs
    Remove-Item $iterationA -ErrorAction SilentlyContinue
    Get-ChildItem -Path $input_logs -Include "$Include" -Recurse | Get-Content | Select-String -Pattern $Pattern | Export-Csv $iterationA -Append
    
    #Interation B export only line to txt format
    Import-Csv $iterationA | select -ExpandProperty Line | Out-File $iterationB
    
    #Interation 3 select all name how login in OWA
    $FindName = Select-String -Path $iterationB -Pattern "($regexEMAILUPN)|($regexEMAILNETBIOS)" -AllMatches | % { $_.Matches } | % { $_.Value } | Get-Unique | group | select Name
    $massive = $FindName.Name.Replace("какоетозначение","")
    
    #Interation 4 Find lastlogon to OWA
    $myArray = @()
    $massive = Get-Content $iterationA
    foreach ($F in $massive) {
    $date =  $massive | Where-Object {($_ -like "*$Pattern*") -and ($_ -like "*$F*")} | select-string -Pattern $regexDATA -AllMatches | % { $_.Matches } | % { $_.Value } | Measure-Latest
    #Add 3 hour to date, cuz in IIS logs have wrong time
    $date = ([datetime]"$date").AddHours(3).ToString("yyyy-MM-dd HH:mm:ss")
    $myObject1 = New-Object System.Object
    $myObject1 | Add-Member -type NoteProperty -name Name -Value "$F"
    $myObject1 | Add-Member -type NoteProperty -name LatestDate -Value "$date"
    
    $myArray += $myobject1
    } 

    Подумал, что я смогу как то увеличить скорость обработки через workflow, но видимо нет.


    4 апреля 2017 г. 9:33
  • Немного подправил

    В 3 операции, получается я беру чей то логин из массива $massive и по очереди прохожусь по всему логу, который я создал из нужных строк. Например лог весит 1.5GB, получается каждый пользователь будет проходиться по всему логу, именно эту операцию я хотел оптимизировать.

    #Interation A select all row with $pattern and compile into one file
    $logs = Get-ChildItem -Path $input_logs -Include "$Include" -Recurse
    Select-String -Path $logs -Pattern $Pattern | select Line | Export-Csv $iterationA
    
    #Interation B select all name who login in OWA
    $FindName = Select-String -Path $iterationA -Pattern "($regexEMAILUPN)|($regexEMAILNETBIOS)" -AllMatches | % { $_.Matches } | % { $_.Value } | Get-Unique | group | select Name
    $massive = $FindName.Name.Replace("значение","")
    
    #Interation C Find lastlogon to OWA
    $myArray = @()
    $alllines = Import-Csv $iterationA | select -ExpandProperty Line
    foreach ($F in $massive) {
    $date =  $alllines | Where-Object {($_ -like "*$Pattern*") -and ($_ -like "*$F*")} | select-string -Pattern $regexDATA -AllMatches | % { $_.Matches } | % { $_.Value } | Measure-Latest
    #Add 3 hour to date, cuz in IIS logs have wrong time
    $date = ([datetime]"$date").AddHours(3).ToString("yyyy-MM-dd HH:mm:ss")
    $myObject1 = New-Object System.Object
    $myObject1 | Add-Member -type NoteProperty -name Name -Value "$F"
    $myObject1 | Add-Member -type NoteProperty -name LatestDate -Value "$date"
    
    $myArray += $myobject1
    }



    • Изменено SharpQ 4 апреля 2017 г. 10:04
    4 апреля 2017 г. 10:03
  • С LogParser явно быстрее код отработает. Да и в одну строку.

    LogParser.exe -i:iisw3c "Select * from C:\*.log where cs-uri-stem LIKE '%/OWA/ev.owa%'" -o:csv | convertfrom-csv | 
    	Group cs-username | ? {$_.Name} | Select Name,@{n="LastLogon";e={ $_.Group | % {([datetime]"$($_.Date) $($_.Time)").AddHours(3)} | Sort | Select  -last 1 }}

    или

    LogParser.exe -i:iisw3c "select cs-username,MAX(date) AS Date,MAX(time) AS Time from C:\*.log where cs-uri-stem LIKE '%/OWA/ev.owa%' and cs-username Like '%' GROUP-o:csv -stats:OFF | convertfrom-csv | sort cs-username

    Если обойтись без LogParser:

    $h = "date","time","s-ip","cs-method","cs-uri-stem","cs-uri-query","s-port","cs-username","c-ip","cs(User-Agent)","cs(Referer)","sc-status","sc-substatus","sc-win32-status","time-taken"

    Select-String *.log -Pattern "/owa/ev.owa" | % {$_.line} | ConvertFrom-Csv -Header $h -Delimiter " " | Group cs-username | Select Name,@{n="LastLogon";e={ $_.Group | Sort {[datetime]"$($_.Date) $($_.Time)"}| Select -last 1 | Foreach {"$($_.Date) $($_.Time)"}}}





    • Изменено KazunEditor 4 апреля 2017 г. 10:42
    • Помечено в качестве ответа SharpQ 4 апреля 2017 г. 12:05
    4 апреля 2017 г. 10:05
    Отвечающий