2009-03-28 2 views
1

Ich habe eine Anwendung, die eine Protokolldatei mit folgendem Format erstellen:Powershell „Erweitert“ Parsen Komponenten Installationszeit zu berechnen, basierend auf Protokolldatei

2009-03-27 15:30:50 Start 
2009-03-27 15:30:51 Starting Component 1 Installation 
2009-03-27 15:30:52 blah 
2009-03-27 15:30:53 blah 
2009-03-27 15:30:54 blah 
2009-03-27 15:30:55 ~~~ Finished Component 1 Installation ~~~ 
2009-03-27 15:30:56 Starting Component 2 Installation 
2009-03-27 15:30:57 blah 
2009-03-27 15:30:58 blah 
2009-03-27 15:30:59 blah 
2009-03-27 15:30:60 ~~~ Finished Component 2 Installation ~~~ 
2009-03-27 15:30:61 Starting Component 3 Installation 
2009-03-27 15:30:62 blah 
2009-03-27 15:30:63 blah 
2009-03-27 15:30:64 blah 
2009-03-27 15:30:65 ~~~ Finished Component 3 Installation ~~~ 
2009-03-27 15:30:66 Finished 

Ich denke, man den Punkt des Formats erhalten.

Die Sache, die ich achive wollen, ist ein Powershell-Skript zu haben, die eine Tabelle von Ergebnis zeigt

  1. Komponentenname
  2. Startzeit
  3. Endzeit
  4. Benötigte Zeit
  5. zurück

Ich nenne es "Advance" Skript, weil es wahrscheinlich gehören wird: Parsing, Formatierung, Erstellen neuer Objekte, etc.

  • Ich bin ein Neuling in Power

Antwort

3

Das folgende Skript, das für Sie tun könnte ... IF Sie vernünftige Zeitwerte zurückgreifen ... mehr als 60 Sekunden in einer Minute sind seltsam (und gab mir ein paar Ausnahmen hier, die großen Kopfschmerzen über das Datum/Zeit-Analyse verursacht, bis ich merkte, warum die Ausnahmen geworfen wurden ...)

$logfile = $args[0] 

$log = get-content $logfile 

$Components = @() 

switch -regex ($log) { 
    "(.*) Starting (.*) Installation" { 
     $c = New-Object PSObject 
     $st = [DateTime]::ParseExact($Matches[1], "yyyy'-'MM'-'dd HH':'mm':'ss", $null) 
     $c | Add-Member -Type NoteProperty -Name Component -Value $Matches[2] 
     $c | Add-Member -Type NoteProperty -Name StartTime -Value $st 
    } 
    "(.*) ~~~ Finished" { 
     $et = [DateTime]::ParseExact($Matches[1], "yyyy'-'MM'-'dd HH':'mm':'ss", $null) 
     $c | Add-Member -Type NoteProperty -Name EndTime -Value $et 
     $c | Add-Member -Type NoteProperty -Name TimeTaken -Value ($c.EndTime - $c.StartTime) 
     $Components += $c 
    } 
} 

$Components 

ich die Ausführungszeit ein wenig nach unten bekommen könnte (um etwa 25 Prozent) w it dem folgenden Code:

$logfile = $args[0] 

foreach ($l in Get-Content $logfile) { 
    if ($l.Length -ge 30) { 
     if ($l.Substring(20,8) -eq "Starting") { 
      $c = New-Object PSObject 
      $st = [DateTime]::ParseExact($l.Substring(0,19), "yyyy'-'MM'-'dd HH':'mm':'ss", $null) 
      $c | Add-Member -Type NoteProperty -Name Component -Value $l.Substring(29, $l.Length - 42) 
      $c | Add-Member -Type NoteProperty -Name StartTime -Value $st 
     } elseif ($l.Substring(24,8) -eq "Finished") { 
      $et = [DateTime]::ParseExact($l.Substring(0,19), "yyyy'-'MM'-'dd HH':'mm':'ss", $null) 
      $c | Add-Member -Type NoteProperty -Name EndTime -Value $et 
      $c | Add-Member -Type NoteProperty -Name TimeTaken -Value ($c.EndTime - $c.StartTime) 
      $c 
     } 
    } 
} 

aber ich finde es viel weniger lesbar als die erste Lösung (allein wartbar lassen). Das hängt sehr stark mit dem Layout der Protokolldatei zusammen.

+0

Danke für das Skript (und Entschuldigung für den Fehler auf die Sekunden!). Das Skript funktioniert funktional sehr gut, aber vom Standpunkt der Leistung ist es langsam, können Sie vielleicht vorschlagen, was könnte es schneller machen? –

+0

Nun, das Skript liest die vollständige Protokolldatei und führt dann die Verarbeitung aus. Ich habe es gerade in einem 800 KiB Logfile versucht und der Unterschied zwischen dem ersten Lesen, dem Parsen und dem Ausführen in einer Pipeline ist nicht wahrnehmbar (tatsächlich ist die Pipeline sogar langsamer). Derzeit keine Ahnung, wie man es schneller machen kann – Joey

+0

Die New-Object und Add-Member-Aufrufe machen hier rund die Hälfte der Laufzeit aus. Parsing mit Regex ist offensichtlich die andere Hälfte (Datum/Zeit-Parsing ist nicht bemerkbar). Das Umschreiben ohne Regex wird jedoch nicht sehr spaßig oder lesbar sein. – Joey