命名って難しい

変数、関数、クラスなどなど実装より命名に毎回悩むタイプの人間による技術についてのメモ。

Wi-Fi Arubaのshow clientsを取得してDBに入れて見える化するまで

無線アクセスポイントが場所により遅いなどトラブルがあり、手作業でログを取得して解析しているチームがあったので、以下の点で手伝ってみました。

  • 自動取得からDB取り込み
  • 見える化(Power BI)

目次

目的

アクセスポイントへのアクセスを見える化して、障害時や問合せ対応のときに即座に参照できるようにする。

やったこと

自動取得からDB取り込み

データの取得

arubaにtelnetで接続し、 show clients というコマンドを実行することでデータが取れるもよう。

www.arubanetworks.com

結果はこうなる

f:id:NotShown:20190815142202p:plain
show clients 結果

データの出力

どうにかCSVにしたかったけれど方法が見つからず、しょうがないのでtelnetのログファイル出力をし、それをどうにかして読み込むことにしました。

f:id:NotShown:20190815142458p:plain
telnet /?

無事、ログファイルはできましたが、コマンドプロンプト上の改行も加味されて出力されてしまうので、コマンドプロンプトの設定を以下のように設定

  • フォント:8
  • ウインドウのサイズ: 幅250 ※環境依存かと思います。

出力データの整形

PowerShellで無理やり組みました。以上。

SignalやSpeedについては 速度と評価が併記されているので、分解して数値として取り込みやすくしました。 #現在では活用できず。。。

<#
 Aruba のログ解析(クライアント)
 telnetから標準出力をテキストとして出力したものを元にCSVとして吐き出す。
#>


# 設定値
$csvPath = "show_clients.csv"
$csvText = ""
$hasHeader = $true
$headers = "Name","IP Address","MAC Address","OS","ESSID","Access Point","Channel","Type","Role","IPv6 Address","Signal","Speed (mbps)"
$TableTitle = "Client List"
$TableTail = "Number of Clients"

# 事前処理
Remove-Item $csvPath -Force -ErrorAction Ignore
$now = (Get-Date)
$text = Get-Content .\show clients.log
$columnIndex = @()

$isSkip = $true

for($i=0; $i -lt $text.Count;$i++){
    $line = $text[$i]
    
    # ヘッダーの取得
    if($line -eq $TableTitle){
        $i += 2;
        $headerText =  $text[$i]
        # ヘッダーテーブルのフォーマット取得
        for($j = 0; $j -lt $headers.Count;$j++){
            $columnIndex += $headerText.IndexOf($headers[$j])
        }
        if($hasHeader){
            $csvText += (("DateTime,"+($headers -join ",")) + "`r`n")
        }
        $i++
        $isSkip = $false
        continue;
    }
    if($text[$i].StartsWith($TableTail)){ $isSkip = $true }

    # スキップ
    if($isSkip){ continue; }

    $csvLine = $line
    for($ci = $columnIndex.Length -1; $ci -gt 0; $ci--){
        $csvLine = $csvLine.Insert($columnIndex[$ci],",")
    }
    $csvText += (("$($now.ToString('yyyy-MM-dd HH:mm:ss.fff')),"+$csvLine) + "`r`n")
}

# Signal とSpeed を分解してわかりやすくする

ConvertFrom-Csv $csvText | 
    select DateTime,
    "Name","IP Address","MAC Address","OS","ESSID","Access Point","Channel","Type","Role","IPv6 Address",
    @{Name="Signal Value";Expression={$_.Signal -replace "\(.*","" }},
    @{Name="Signal Grade";Expression={$_.Signal -replace "[\d\(\)]",""}},
    @{Name="Speed (mbps) Value";Expression={$_."Speed (mbps)" -replace "\(.*","" }},
    @{Name="Speed (mbps) Grade";Expression={$_."Speed (mbps)" -replace  "[\d\(\)]",""}} |
    ConvertTo-Csv -NoTypeInformation |
    %{ $_.Replace('"','') -replace " +,",',' } | 
    Set-Content -Path $csvPath

データ取得処理の自動化

単純なのでVBScriptでオートメーション化しました。

command="show clients"
path="C:\Aruba\"& command &".log"
ip=""
userId=""
password =""

set oShell = CreateObject("WScript.Shell")
oShell.run "Telnet -f " & path
WScript.Sleep 1000
oShell.SendKeys("Open " & ip & "{Enter}")
WScript.Sleep 5000
oShell.SendKeys(userId & "{ENTER}")
WScript.Sleep 1000
oShell.SendKeys( password & "{ENTER}")
WScript.Sleep 1000
oShell.SendKeys(command & "{ENTER}")
WScript.Sleep 10000
oShell.SendKeys("exit{ENTER}")
WScript.Sleep 500
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("quit{Enter}")
WScript.Sleep 1000

データの取り込み

bcp コマンドで取り込み

docs.microsoft.com

見える化(Power BI)

アクセス数

情報取得した時間のアクセス数はMACアドレスのユニークカウントとしました。 また、下記の観点でアクセス数を絞り込みます。 - アクセスポイント名 - SSID

フロアマップで見たくない?

BI製品の宣伝によくある「地図上に円がプロットされて、円のサイズでその数字を表す!」なグラフを作りたい、と思ったので散布図を活用して試してみました。

散布図に必要なデータは以下のようにしています。

  • 日時:取得日時
  • X座標:フロアマップのX座標
  • Y座標:フロアマップのY座標
  • 値:アクセスしているクライアント数

座標のとり方

Excelにフロアマップ画像を貼り付けて、背景色を透過することで力技で座標を設定。 アクセスポイント名をリレーションのキーとして紐付けます。

アクセスポイント名 X座標 Y座標
AP_FUGA 2 9
AP_HOGE 8 7
AP_FOO 7 2

出来上がり

f:id:NotShown:20190815164329p:plain
PowerBI フロアマップ散布図

中心はずれているけれど大体あえばいい。 とりあえず、なんとなく形になったので完成。

大体合計1.5日くらいかかりましたが、満足の出来です。 取り込み処理も定期実行に載せたのでこれからデータがじわじわ貯まるのが楽しみです。 これで集中しているAPなどが一目で分かり、次のアクションにつながるとよいなと思っています。