Trunca um arquivo de log por datetime usando o Powershell 2.0

0

Nós temos um arquivo de log simples. Fica muito grande ou as entradas são irrelevantes à medida que envelhecem. As entradas têm um prefixo de data e hora semelhante a este:

01/22/15 01:54:17 -I- Start processing stuff

Ocasionalmente, as entradas de registro abrangem várias linhas como esta:

01/23/15 01:18:00 -E- java.io.IOException: (101) Error between keyboard and chair
     at this.mod.no.worky(what_were_you_thinking:duh)

Queremos simplesmente remover as entradas (inteiras) antes de uma data limite, por exemplo, 30 dias.

Soluções que truncam para um número fixo de linhas ou bytes não funcionam neste caso.

Tentativa mais recente com desempenho terrível:

$cutDatePtrn = "^" + (get-date).AddDays(-30).tostring("MM/dd/yy ")
$newStartLine = (select-string -Path $logFile -Pattern $cutDatePtrn -Quiet -List).LineNumber
$tmp = $logFile + '.tmp'
get-content $logFile | select -skip $newStartLine | out-file $tmp
    
por Vic 26.02.2015 / 19:20

1 resposta

2

Aqui está a solução do PowerShell usando Streams. Leva ~ 60 segundos para processar o arquivo de 1GB no meu laptop ( i3 2.5GHz, 4GB de RAM, 5400RPM HDD) . Ainda é três vezes mais lento do que LogParser , embora:

LOGPARSER "Select Text from C:\Path\To\log.file where Text like '01/22/15%'" -i:TEXTLINE -q:Off
$LogFolder = 'c:\Path\To\Log\Folder'
$Filter = '*.log'
$Postfix = '.tmp'
$cutDatePtrn = '^' + (Get-Date).AddDays(-30).ToString('MM/dd/yy')

# Iterate over each log file in the $LogFolder
Get-ChildItem -LiteralPath $LogFolder -Filter $Filter |
    ForEach-Object {
        Write-Host "Current file: $($_.FullName)"
        $InFile = New-Object -TypeName System.IO.StreamReader -ArgumentList $_.FullName

        Write-Host 'Processing file...'

        $WriteFile = $false
        while(($line = $InFile.ReadLine()) -ne $null)
        {
            if((-not $WriteFile) -and ($line -notmatch $cutDatePtrn))
            {
                continue
            }
            elseif((-not $WriteFile) -and ($line -match $cutDatePtrn))
            {
                Write-Host 'Found match:'
                Write-Host $line

                $WriteFile = $true
                $TmpFile = $_.FullName + $Postfix

                Write-Host "Creating new temporary file: $TmpFile"
                $OutFile = New-Object -TypeName System.IO.StreamWriter -ArgumentList $TmpFile, $false
            }

            $OutFile.WriteLine($line)
        }

        Write-Host 'Done processing, cleaning up...'
        if($OutFile)
        {

            $OutFile.Flush()
            $OutFile.Close()
            $OutFile.Dispose()
        }

        $InFile.Close()
        $InFile.Dispose()

        if(Test-Path $TmpFile -PathType Leaf)
        {
            Write-Host "Deleting original file: $($_.FullName)"
            Remove-Item -Path $_.FullName -Force

            Write-Host "Renaming temporary file: $TmpFile -> $($_.FullName)"
            Rename-Item -Path $TmpFile -NewName $_.FullName -Force
        }

        Write-Host "Finished processing file: $($_.FullName)"
        }
    
por 25.03.2015 / 15:36

Tags