小ネタです。
ふと、「Bash on Ubuntu on Windowsを使えばWindowsでもロードアベレージを取得できるよなぁ…」と思ったので実際に試してみました。
Windowsのロードアベレージ
上の記事に詳細が説明されていますが、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でロードアベレージを取得するにはtop
、uptime
といったコマンドや/proc/loadavg
を参照すれば可能です。
やり方はいろいろありますが、今回は/proc/loadavg
を参照する方法で2パターン試してみました。
方法.1
最初の方法はこんな感じです。
# PowerShell 'cat /proc/loadavg|awk ''{print "@{Load1="$1";Load5="$2";Load15="$3";}"}'';exit;' | bash | iex
実行結果)
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];}}
実行結果)
こちらは、Bashでは/proc/loadavg
の値を取得するだけにして、PowerShellで値の成形をする様にしています。
他にもいろいろなやり方があると思います。
BashとPowerShellをどういった塩梅で組み合わせるかを考えるのはとても楽しいです。
残念なお知らせ
ここまで書いておいてアレなのですが非常に残念なお知らせがあります。
このエントリの内容を試している最中にロードアベレージの値が全然変化せず、違和感を感じたので調査してみたところ、以下のIssueが上がっていました。
現時点ではBash on Ubuntu on Windowsのロードアベレージは0.52 0.58 0.59
のダミー値を返すというふざけた状態でした…*2
まだベータ版ですので値が取れないのは仕方ないと思いますが、せめて0 0 0
といった自明な値にしておいてほしいものです。
こちらについては気長に待つしかないといったところでしょう。
最後に
最後にとんでもないオチがついてしまいましたがこんな感じです。
本エントリは現時点では全く役に立ちませんが、いずれ役に立つ日がくると信じています。
いまのところはBashとPowerShellを組み合わせて使う一例として見ていただければと思います。