Afficher les métriques SMB avec influxDB et Grafana

Afficher les métriques SMB avec influxDB et Grafana

Introduction

Récemment on m'a demandé de créer un dashboard qui affiche les stats SMB Share suivantes:

'\SMB Server Shares(*)\Avg. sec/Read',
'\SMB Server Shares(*)\Avg. sec/Write',
'\SMB Server Shares(*)\Avg. sec/Request',
'\SMB Server Shares(*)\Current Open File Count',
'\SMB Server Shares(*)\Current Pending Requests',
'\SMB Server Shares(*)\Tree Connect Count',
'\SMB Server Shares(*)\Read Bytes/sec',
'\SMB Server Shares(*)\Write Bytes/sec'

Voici comment j'ai fait:

  1. J'ai créé un Bucket "SMBInfo" dans InfluxDB
  2. J'ai créé un script powershell qui se connecte sur une liste de serveurs et qui exportent les valeurs dans mon bucket InfluxDB
  3. J'ai schedulé une job qui roule mon script powershell aux 2 minutes avec Rundeck
  4. J'ai connecté Grafana sur le bucket InfluxDB pour afficher le data

InfluxDB

J'ai crée une clé API qui donne read / write à mon bucket SMBInfo.

J'ai 2 measurement

    • smb_share_metrics
    • smb_sessions_metrics

Pour smb_share_metrics j'ai 2 tags

    • server
    • share

Pour smb_sessions_metrics j'ai 3 tags

    • server
    • user
    • workstation

Powershell

Je voulais seulement les shares de users, pas les shares admin donc dans le script j'ai filtré tout ce qui est admin

   try {
        $Samples = Get-Counter $CounterPaths -ErrorAction Stop |
            Select-Object -ExpandProperty CounterSamples |
            Where-Object {
                $_.InstanceName -ne "_Total" -and
                $_.InstanceName -notmatch '^\w\$' -and
                $_.InstanceName -notlike '*admin$*' -and
                $_.InstanceName -notlike '*ipc$*'
            }

Il ne faut pas oublier de convertir le timestamp dans un format que InfluxDB accepte:

$Ms = ((Get-Date).ToUniversalTime() - (Get-Date '1970-01-01T00:00:00Z')).TotalMilliseconds
$Timestamp = [int64]$Ms * 1000000

Pour les sessions SMB je voulais le nom du serveur, le username, le worksation et le nombre de sessions ouvertes pour cet usager.

try {
        $Sessions = Get-SmbSession -ErrorAction Stop

        foreach ($Session in $Sessions) {
            $Output += [PSCustomObject]@{
                Type = "Session"
                Server = $env:COMPUTERNAME
                ClientUserName = $Session.ClientUserName
                ClientComputerName = $Session.ClientComputerName
                NumOpens = $Session.NumOpens
            }
        }
    }

Avec cette information j'ai aussi pu créer un dashboard focuser sur l'information des usagers.

Rundeck

Pour rouler mon script régulièrement j'ai pris Rundeck mais task scheduler pourrait aussi bien fonctionner.

L'avantage que j'aime avec rundeck c'est que si la job failed j'envoie un message dans un channel Teams.

Grafana

Dans Grafana on crée un data source InfluxDB pour le dashboard.

En haut du dashboard j'ai ajouté 2 variables pour pouvoir filtrer soit par Serveur, soit par Share.

La query Flux ressemble à cela:

from(bucket: "SMBInfo")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) =>
      r._measurement == "smb_share_metrics" and
      r._field == "open_files"
  )
  |> filter(fn: (r) => r.server =~ /${Server:regex}/)
  |> filter(fn: (r) => r.share =~ /${Share:regex}/)
  |> aggregateWindow(
      every: v.windowPeriod,
      fn: last,
      createEmpty: false
  )

On peut se servir du Time Picker de Grafana pour zoomer sur une période de temps.

Pour afficher un autre counter, il suffit de changer le r.field

from(bucket: "SMBInfo")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) =>
      r._measurement == "smb_share_metrics" and
      r._field == "pending_requests"
  )
  |> filter(fn: (r) => r.server =~ /${Server:regex}/)
  |> filter(fn: (r) => r.share =~ /${Share:regex}/)
  |> aggregateWindow(
      every: v.windowPeriod,
      fn: mean,
      createEmpty: false
  )

Tu crées un panel par counter que tu as exporter.

Pour le dashboard avec l'information des users c'est le même principe. Par contre j'ai ajouté 3 variables comme filtres

    • User
    • Server
    • Workstation

La variable Server dépend de la variable user. C'est à dire que la query pour retourner les servers dépend du user que tu as choisis. Ainsi, seulement les serveurs que le user a utilisé va s'afficher.

La variable Workstation dépend de User et de Server.