TerminalSystemMonitor.jl の紹介

# 本日は

アドベントカレンダーの $N=13$ 日目の記事です．

自作パッケージ TerminalSystemMonitor.jl の紹介です．`htop` コマンドの機能にある CPU, メモリの使用量を確認できる素朴なパッケージです．

https://github.com/AtelierArith/TerminalSystemMonitor.jl?tab=readme-ov-file

こんなことができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/a7b2297c-8c89-73c9-5c78-ef2e33410dc8.png)


## 作成の背景

`top` というコマンドがあります．

```
top – display sorted information about processes
```

どのようなプロセスが動いているかのような情報を監視することができます．

また `htop` というコマンドがあります．CPU，メモリ の使用状況を視覚的に見ることができます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/aa95b27f-825a-2934-a7b1-fd9f0760101c.png)

最近ですと Rust 製による `btm` というコマンドがあります．これは top の対義語としての bottom の略だと思われます．

https://github.com/ClementTsang/bottom

> Yet another cross-platform graphical process/system monitor.

インストールの手順は下記の通りです．

https://github.com/ClementTsang/bottom?tab=readme-ov-file#installation

`btm` コマンドの使い方は `htop` とほぼ同じで

```sh
$ btm --basic 
```

で `htop` ライクな出力を出します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/e435ea77-3f0b-e474-ffa1-2502b7b78173.png)


`btm` 単体で実行するともう少しリッチな見え方が可能です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/33fb285e-0310-27de-71f0-6c318f19cd8a.png)

また，`watch nvidia-smi`, `nvtop` のように NVIDIA の GPU の使用率のモニタリングツールもありますね．

他にも macOS だと `mactop`, `macmon` などなどあります．これは P, E コア別にCPUの使用状況を確認することができます．

他にありましたら教えてください．

### 表示上の問題点

`htop` は搭載されている CPU のコア数が大きくなると CPU の使用率の視認性が悪化しがちです．
ターミナルのサイズを画面の半分にすると次のようになります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/9ec82e37-77c3-064a-2a81-f3c11f00d537.png)

20 コア 40 スレッドのマシンで `htop` を実行し MacBook 16 inch の画面右半分で表示させた場合です．なるほどわからん．`btm --basic`  だと横幅に関しては視認性が解消されてますが縦方向で短くなると全てのコアの表示を諦めてしまいます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/ae69f9e9-37c1-126d-4d25-6acf75e009ff.png)

「とりあえず計算機の CPU 使用率がどうなっているか（並列計算で全てのCPUが100% 使ってるか） メモリ使いすぎておらず OOM にならないか心配」という目的だと若干難儀です．

---

### 単純に作りたかった

はい．実は Web 版として Dash.jl を使ったものは作っていました．ターミナル上でシンプルに動く版はなかったのでいつか作るかということで作ってみることにしました．

https://github.com/plotly/Dash.jl/issues/50#issuecomment-1033972687

## 動かしてみよう

```julia
julia> using Pkg; Pkg.add("TerminalSystemMonitor")
julia> using TerminalSystemMonitor; monitor()
```

これでできます．依存パッケージは Dates.jl UnicodePlots.jl, Term.jl, MLDataDevices.jl という Julia パッケージです．これらは Windows 上でも動くはずなので多くのプラットフォームで動作するようになっています．

またレイアウトもターミナルの横幅のサイズに応じて表示するブロックを縦側に押し付けて全部表示させようと頑張っています．レスポンシブデザインというとカッコいいですね :sunglasses: 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/79437b01-68b3-1ebe-35a0-40390a861190.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/a6f226c9-d863-3383-38d5-d8b78a2efcca.png)

CPU, メモリ使用量以外の情報（例えばCPU温度，プロセス）は取得の仕方がわからないのでつけてません．

Julia ではマシンの保有するメモリ最大値は `libuv` を使って調べています．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/a67b8eac-2542-6db7-56dd-b265d6986103.png)

libuv 自体は元々は Node.JS を主眼に作られたライブラリのようですが Julia も実は使っているのです．

https://docs.libuv.org/en/v1.x/misc.html#c.uv_get_constrained_memory

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/6b463a83-87cb-815d-0b7a-573c58e3d24c.png)

https://github.com/libuv/libuv

よって `libuv` がサポートしている機能があれば `ccall` を使って呼び出すことができます．

## NVIDIA GPU の使用率，メモリ消費量をみたい

- 事前に `CUDA.jl` をインストールします．
- Julia の TerminalSystemMonitor.jl をロードする前に `using CUDA` を実行しておきます．つまり次のコマンドを実行すればOKです．

```julia
julia> using CUDA; using TerminalSystemMonitor; monitor()
```

下記のようになっていると思います． 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/4d553dd8-a1ab-693a-ad00-4f2044173877.png)

取得に用いている情報は CUDA.jl ソースコードを読んで API を探し出して見つけています．よって Julia, CUDA.jl が適切にインストールされているシチュエーションではうまく動作するはずです．

事前に `using CUDA` が必要な理由はパッケージエクステンションという機能を用いているからです．CUDA.jl がロードされているとこの機能を使える仕組みにしています．これは必ずしも NVIDIA GPU が載っていないマシンでも動作をさせたいからです．

## Apple シリコンののGPUの使用状況を見たい

Julia だと Metal.jl がありますが，やり方わからん！誰かすごい人教えて．現状で最適なツールは `macmon` を入れてもうのが良いと思います．

https://github.com/vladkens/macmon

多くのツール，例えば `mactop`, `asitop` は `powermetrics` というルート権限が必要なコマンドを内部で実行しその情報をパースして得ています．macmon は別のアプローチを用いています．`CFString` とかを使っているので https://developer.apple.com/documentation/corefoundation を気合を読んで読む必要があります．CoreFoundation に関しては `satoshin2071` さんが公開されている gist を読むか Objective C を勉強する必要がありますね．

https://gist.github.com/satoshin2071/aefc23c2aa968cc27fe3

う~~~~~~~~ 得意な方がいればアドバイスお願いします．

以上