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:
- J'ai créé un Bucket "SMBInfo" dans InfluxDB
- J'ai créé un script powershell qui se connecte sur une liste de serveurs et qui exportent les valeurs dans mon bucket InfluxDB
- J'ai schedulé une job qui roule mon script powershell aux 2 minutes avec Rundeck
- 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 * 1000000Pour 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.