Graphiques Ascii et remplissage datastores

Dans plusieurs vues il y a une représentation graphique simplifiée de la consommation de certaines ressources. Par exemple, la vue hosts permet de visualiser rapidement la consommation CPU et Mémoire des différents ESXi.
Cependant, il n’y a pas d’équivalent pour les datastores : les données de remplissage sont uniquement sous formes de chiffres. De plus, si on a des clusters de datastores, il faut aller dans chaque cluster pour voir le remplissage de chaque datastore.

Le but de ce script est d’effectuer une représentation « graphique en mode texte » (si si, je vous assure). Ce n’est pas de l’Ascii Art, mais c’est la même idée.

Je m’appuie sur une fonction qui affiche une jauge de remplissage en fonction de certains critères.
Il sera possible de l’utiliser pour représenter n’importe quelle jauge, et plus particulièrement le remplissage des datastores


La fonction

Function Show-ProgressBar($Value, $Max, $GraphWidth, $GraphMaxWidth, $PreLabel, $PostLabel)
{
   $GraphValue = $Value / $Max * $GraphWidth
   Write-Host -NoNewline $PreLabel
   Write-Host -NoNewline [
   For ($NumChar = 1 ; $NumChar -le $GraphValue; $NumChar++)
   {
      If ($NumChar -lt $GraphWidth * $WarningThreshold / 100) {Write-Host -NoNewline -ForegroundColor Green $ProgressCharFull}
      ElseIf ($NumChar -lt $GraphWidth * $AlertThreshold / 100) {Write-Host -NoNewline -ForegroundColor Yellow $ProgressCharFull}
      Else {Write-Host -NoNewline -ForegroundColor Red $ProgressCharFull}
   }
   For ($NumChar = $NumChar ; $NumChar -le $GraphWidth ; $NumChar++) {Write-Host -NoNewline $ProgressCharEmpty}
   Write-Host -NoNewline ]
   For ($NumChar = $GraphWidth + 1 ; $NumChar -le $GraphMaxWidth ; $NumChar++) {Write-Host -NoNewline $ProgressCharEmpty}
   Write-Host $ProgressCharEmpty $PostLabel
}

Les variables de la fonction

Voici les variables à passer à la fonction :
– $Value : Valeur de la jauge
– $Max : Valeur maximale de la jauge
– $GraphWidth : Largeur de la jauge (en caractères)
– $GraphMaxWidth : Largeur de la jauge la plus large
– $PreLabel : Texte affiché avant la jauge
– $PostLabel : Texte affiché à droite de la jauge
La variable GraphMaxWidth est utile si on veut représenter les échelles relatives de différentes jauges.
Par exemple si on a des datastores de 2 To et d’autres de 3 To, on peut représenter des jauges de taille différentes, la première représentant les 2/3 de la seconde.
Ce n’est bien sûr utile que si les ordres de grandeur sont les mêmes. Si un datastore interne fait 100 Go et un datastore NFS fait 12 To, la différence d’échelle fera que le premier graphe fera moins de 1 caractère de large.

Deux autres variables sont nécessaires et doivent être définies à l’avance :
– $ProgressCharFull : Caractère à utiliser pour la partie pleine de la jauge. Perso j’utilise « [char]9632 ».
– $ProgressCharEmpty : Caractère à utiliser pour la partie vide de la jauge. Perso j’utilise « [char]183 » ou l’espace, selon l’effet voulu.

Ca m’avait semblé lourd de les ajouter à l’appel de la fonction, car il me semble qu’on va toujours utiliser les mêmes caractères pour une meilleure lisibilité des différentes jauges.

Exemple d’affichage

Si on lance ces différents appels à fonction :

Show-ProgressBar 0 100 50 70 " " "  0 / 100, GraphWidth = 50, GraphMaxWidth = 70"
Show-ProgressBar 40 100 50 70 " " " 40 / 100, GraphWidth = 50, GraphMaxWidth = 70"
Show-ProgressBar 70 100 50 70 " " " 70 / 100, GraphWidth = 50, GraphMaxWidth = 70"
Show-ProgressBar 90 100 50 70 " " " 90 / 100, GraphWidth = 50, GraphMaxWidth = 70"
Show-ProgressBar 100 100 50 70 " " "100 / 100, GraphWidth = 50, GraphMaxWidth = 70"
Write-Host
Show-ProgressBar 0 100 60 70 " " "  0 / 100, GraphWidth = 60, GraphMaxWidth = 70"
Show-ProgressBar 40 100 60 70 " " " 40 / 100, GraphWidth = 60, GraphMaxWidth = 70"
Show-ProgressBar 70 100 60 70 " " " 60 / 100, GraphWidth = 60, GraphMaxWidth = 70"
Show-ProgressBar 90 100 60 70 " " " 90 / 100, GraphWidth = 60, GraphMaxWidth = 70"
Show-ProgressBar 100 100 60 70 " " "100 / 100, GraphWidth = 60, GraphMaxWidth = 70"
Write-Host
Show-ProgressBar 0 100 70 70 " " "  0 / 100, GraphWidth = 70, GraphMaxWidth = 70"
Show-ProgressBar 40 100 70 70 " " " 40 / 100, GraphWidth = 70, GraphMaxWidth = 70"
Show-ProgressBar 70 100 70 70 " " " 60 / 100, GraphWidth = 70, GraphMaxWidth = 70"
Show-ProgressBar 90 100 70 70 " " " 90 / 100, GraphWidth = 70, GraphMaxWidth = 70"
Show-ProgressBar 100 100 70 70 " " "100 / 100, GraphWidth = 70, GraphMaxWidth = 70"

Voilà ce qu’on obtient :

graphiques-ascii-et-remplissage-datastores-01

Il n’y a plus qu’à parcourir les datastores et clusters de datastores en appelant cette fonction pour effectuer l’affichage.


Variables du script

En plus des variables utilisés par la fonction, il faut initialiser cette variable.

$Proportional : booléen indiquant par $true ou $false si l’affichage des jauges doit être proportionnel.

Pour le reste, vous adapterez les requêtes de datastores ou de clusters de datastores à vos besoins.

Exemple de résultat en mode proportionnel :

graphiques-ascii-et-remplissage-datastores-02

Et les mêmes valeurs en mode non proportionnel :

graphiques-ascii-et-remplissage-datastores-03


Script

Function Show-ProgressBar($Value, $Max, $GraphWidth, $GraphMaxWidth, $PreLabel, $PostLabel)
{
   $GraphValue = [int]($Value / $Max * $GraphWidth)
   Write-Host -NoNewline $PreLabel
   Write-Host -NoNewline [
   For ($NumChar = 1 ; $NumChar -le $GraphValue; $NumChar++)
   {
      If ($NumChar -lt $GraphWidth * $WarningThreshold / 100) {Write-Host -NoNewline -ForegroundColor Green $ProgressCharFull}
      ElseIf ($NumChar -lt $GraphWidth * $AlertThreshold / 100) {Write-Host -NoNewline -ForegroundColor Yellow $ProgressCharFull}
      Else {Write-Host -NoNewline -ForegroundColor Red $ProgressCharFull}
   }
   For ($NumChar = $NumChar ; $NumChar -le $GraphWidth ; $NumChar++) {Write-Host -NoNewline $ProgressCharEmpty}
   Write-Host -NoNewline ]
   For ($NumChar = $NumChar ; $NumChar -le $GraphMaxWidth ; $NumChar++) {Write-Host -NoNewline " "}
   Write-Host " " $PostLabel
}

$DatastoreClusters = Get-DatastoreCluster dsc* | Sort-Object -Property Name
$Datastores = Get-Datastore iscsi* | Sort-Object -Property Name
$DatastoreClusterDatastores = $DatastoreClusters | Get-Datastore | Sort-Object -Property Name
$AloneDatastores = $Datastores | where-object {$DatastoreClusterDatastores -notcontains $_}
$MaxDatastoreClusterTotallGB = ($DatastoreClusters.CapacityGB | Measure-Object -Maximum).Maximum
$MaxDatastoreClusterTotallSize = ([int]$MaxDatastoreClusterTotallGB).ToString().Length
$MaxDatastoreTotallGB = ($Datastores.CapacityGB | Measure-Object -Maximum).Maximum
$MaxDatastoreTotallSize = ([int]$MaxDatastoreTotallGB).ToString().Length
$Proportional = $true
$ProgressCharFull = [char]9632
$ProgressCharEmpty = [char]183
Foreach ($DatastoreCluster in $DatastoreClusters)
{
   Write-Host -ForegroundColor Gray -NoNewline 'Datastore Cluster '
   Write-Host -ForegroundColor White $DatastoreCluster
   $DatastoreClusterConsumed = $DatastoreCluster.CapacityGB - $DatastoreCluster.FreeSpaceGB
   $Label = "{0,1} {1,$MaxDatastoreClusterTotallSize} {2,4} {3,$MaxDatastoreClusterTotallSize} {4,4}" -f "[", [int]$DatastoreClusterConsumed, "GB /", [int]$DatastoreCluster.CapacityGB, "GB ]"
   If ($Proportional)
   {
      $DatastoreClusterGraphLength = $DatastoreCluster.CapacityGB / $MaxDatastoreClusterTotallGB * 100
   }
   Else
   {
      $DatastoreClusterGraphLength = 100
   }
   Show-ProgressBar $DatastoreClusterConsumed $DatastoreCluster.CapacityGB $DatastoreClusterGraphLength 100 "" $Label
   Write-Host
   $DatastoreClusterDatastores = $DatastoreCluster | Get-Datastore | Sort-Object -Property Name
   Foreach ($Datastore in $DatastoreClusterDatastores)
   {
      $DatastoreConsumed = $Datastore.CapacityGB - $Datastore.FreeSpaceGB
      $Label = "{0,1} {1,$MaxDatastoreTotallSize} {2,4} {3,$MaxDatastoreTotallSize} {4,4} {5,-20}" -f "[", [int]$DatastoreConsumed, "GB /", [int]$Datastore.CapacityGB, "GB ]", $Datastore.Name
      If ($Proportional)
      {
         $DatastoreGraphLength = $Datastore.CapacityGB / $MaxDatastoreTotallGB * 50
      }
      Else
      {
         $DatastoreGraphLength = 50
      }
      Show-ProgressBar $DatastoreConsumed $Datastore.CapacityGB $DatastoreGraphLength 50 "`t" $Label
   }
   Write-Host
}
Write-Host
If (($AloneDatastores | Measure-Object).count -ne 0)
{
   Write-Host -ForegroundColor gray 'Standalone datastores'
   Foreach ($Datastore in $AloneDatastores)
   {
      $DatastoreConsumed = $Datastore.CapacityGB - $Datastore.FreeSpaceGB
      $Label = "{0,1} {1,$MaxDatastoreTotallSize} {2,4} {3,$MaxDatastoreTotallSize} {4,4} {5,-20}" -f "[", [int]$DatastoreConsumed, "GB /", [int]$Datastore.CapacityGB, "GB ]", $Datastore.Name
      If ($Proportional)
      {
         $DatastoreGraphLength = $Datastore.CapacityGB / $MaxDatastoreTotallGB * 50
      }
      Else
      {
         $DatastoreGraphLength = 50
      }
      Show-ProgressBar $DatastoreConsumed $Datastore.CapacityGB $DatastoreGraphLength 50 "`t" $Label
   }
   Write-Host
}

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *