Out-ASCIIChart

Es muss nicht immer Excel, Power Bi, o.ä. sein, wenn ich nur mal schnell ein paar Zahlen sichtbar vergleichen will.

Aufgabenstellung

Ich habe auf der Seite Remote Move Request ohne ADSync beschrieben, wie ich Postfächer von einem Exchange OnPremises Server in die Cloud migrieren kann und wollte die lokalen IIS-Logs hinsichtlich der Zugriffe auf den MRSProxy auswerten. Klar könnte ich nun Megabyte IIS_Logs in PowerBI einlesen und hochauflösende interaktive Grafiken machen. Ich wollte aber eigentlich nur sehen, zu welchen Zeiten viel viele Request beim Server aufgelaufen sind, um die Migration besser zu verstehen

Daher habe ich mir ein kleines Skript geschrieben, welches die IIS-Logs geparst und dann in konfigurierbaren Intervallen zusammengefasst hat. Hier ein Beispiel mit Zusammenfassungen nach der Stunde.

Menschen sind aber sehr schwer im Vergleichen von Zahlen und wenn das hier ja noch geht, so kann eine Migration auch über mehrere Tage gehen.

ASCII-Chart

Also habe ich mit die Ausgabe von "Count" und "Name "genommen und in eine kleine Grafik verpackt.

Ich habe einfach alle Werte über die Pipeline angenommen und erst einmal das Maximum gesucht. Das Skript hat dann noch die aktuelle Breite der Console ermittelt und pauschal mal 10 Zeichen für die Ausgabe von Name und Count abgezogen. Die neue Spalte "barchart" habe ich dann mit der entsprechenden Anzahl an Rauten aufgefüllt.

Code

Der Code ist so einfach und überschaubar, dass ich ihn hier einfach einstelle.

out-asciichart.ps1

Wenn Sie die ganzen Kommentare und Write-Verbose-Zeilen noch entfernen, dann wäre es schon fast ein Einzeiler:

# Out-Asciichart
#
# Expects output ov "group-object" with the properties "name" and "Count" to produce a minimalisic Asciichart
#
#  .\convertfrom-iislog.ps1   |  group  timestamp | .\out-asciichart.ps1 -Verbose

[cmdletbinding()]
param (
    [Parameter(ValueFromPipeline)]
    $input,
    $width = 0
)

$buffer= $input | select name,count,barchart
[long]$maxname= ($buffer | Foreach {$_.name.length + $_.count.tostring().length} | Measure-Object -Maximum).Maximum
[long]$maxcount= ($buffer |  Measure-Object -Property count -Maximum).Maximum
Write-Verbose "TotalElements: $($buffer.count)"
Write-Verbose "ConsoleWidth : $($Host.UI.RawUI.WindowSize.Width)"
Write-Verbose "MaxName      : $($maxname)"
Write-Verbose "MaxCount     : $($maxcount)"
if ($width -eq 0) {
    $width = $Host.UI.RawUI.WindowSize.Width - $maxname - 10
}
Write-Verbose "MaxBarWidth  : $($width)"

Foreach ($entry in $buffer) {
    $entry.barchart =  ("").PadLeft(($entry.count/$maxcount*$width),"#")
}
$buffer

Die Ausgabe erfolgt wieder in die Pipeline. Sie können Sie also jederzeit anderweitig weiter verwenden.

Weiterentwicklung

Ich habe schon überlegt, ob ich vielleicht eine logarithmische Ausgabe addiere, denn eine lineare Skalierung passt nicht immer. Aber dann wird das Interpretieren der Daten kniffliger, denn ich addiere ja keine Achsenbeschriftung. Die nächste Entwicklungsstufe ist sicherlich die Ausgabe als richtige Grafiken, z.B. als generiertes Bild oder Webseite zur Anzeige im Browser oder Winforms.

Weitere Links