しばたテックブログ

気分で書いている技術ブログです。

Windows 10でロードアベレージを取得する?

小ネタです。

ふと、「Bash on Ubuntu on Windowsを使えばWindowsでもロードアベレージを取得できるよなぁ…」と思ったので実際に試してみました。

Windowsのロードアベレージ

www.atmarkit.co.jp

上の記事に詳細が説明されていますが、WindowsではUNIXやLinuxのロードアベレージと同等の値を取得することはできません。
類似の値としてパフォーマンスカウンターの\System\Processor Queue Lengthが紹介されており、通常はこれを使うしかありません。

PowerShellでこの値を取得するにはGet-Counterコマンドを使い以下の様にすれば良いです。

(Get-Counter -Counter "\System\Processor Queue Length").CounterSamples.CookedValue

このカウンターはデフォルトのスケールが1なのでCookedValueがそのまま使えます。

また、平均を取るには以下の様な感じすれば一応可能です。*1
(以下のサンプルを実行すると1分間待たされるので注意してください)

# UNIX/Linuxでのサンプリング間隔は5秒だそうなので、それに合わせて1分間の平均を求めます
(Get-Counter -Counter "\System\Processor Queue Length" -SampleInterval 5 -MaxSamples 12).CounterSamples.CookedValue `
    | Measure-Object -Average | Select-Object -ExpandProperty Average

Windows 10でロードアベレージを取得する

Windows 10でWSLを有効にすればWindows内でUbuntuが動作しますので、Ubuntu経由でロードアベレージの値が取得できるはずです。

Ubuntuでロードアベレージを取得するにはtopuptimeといったコマンドや/proc/loadavgを参照すれば可能です。

f:id:stknohg:20170427225852p:plain

f:id:stknohg:20170427230745p:plain

f:id:stknohg:20170427225912p:plain

やり方はいろいろありますが、今回は/proc/loadavgを参照する方法で2パターン試してみました。

方法.1

最初の方法はこんな感じです。

# PowerShell
'cat /proc/loadavg|awk ''{print "@{Load1="$1";Load5="$2";Load15="$3";}"}'';exit;' | bash | iex

実行結果)

f:id:stknohg:20170427230256p:plain

UbuntuのBashで/proc/loadavgの値を取得、awkでPowerShellのHashTableの書式(@{Load1=$1;Load5=$2;Load15=$3;})に成形し、Invoke-Expression(iex)でHashTableに変換しています。

方法.2

もう一つの方法はこんな感じです。

# PowerShell
'cat /proc/loadavg;exit;' | bash | % {$v=-split $_;@{Load1=$v[0];Load5=$v[1];Load15=$v[2];}}

実行結果)

f:id:stknohg:20170427230307p:plain

こちらは、Bashでは/proc/loadavgの値を取得するだけにして、PowerShellで値の成形をする様にしています。

他にもいろいろなやり方があると思います。
BashとPowerShellをどういった塩梅で組み合わせるかを考えるのはとても楽しいです。

残念なお知らせ

ここまで書いておいてアレなのですが非常に残念なお知らせがあります。

このエントリの内容を試している最中にロードアベレージの値が全然変化せず、違和感を感じたので調査してみたところ、以下のIssueが上がっていました。

github.com

現時点ではBash on Ubuntu on Windowsのロードアベレージは0.52 0.58 0.59のダミー値を返すというふざけた状態でした…*2
まだベータ版ですので値が取れないのは仕方ないと思いますが、せめて0 0 0といった自明な値にしておいてほしいものです。

こちらについては気長に待つしかないといったところでしょう。

最後に

最後にとんでもないオチがついてしまいましたがこんな感じです。
本エントリは現時点では全く役に立ちませんが、いずれ役に立つ日がくると信じています。

いまのところはBashとPowerShellを組み合わせて使う一例として見ていただければと思います。

*1:実運用では使えないと思いますが…

*2:しばらく普通に騙されてましたよ…