はじめに
研究室で計算機サーバーを管理していると、PCの使用率などを常に確認する必要があります。しかし、Linuxに不慣れな研究室メンバーもいるため、「大きな計算を実行する前にPCのCPU使用率をチェックしてください」とアドバイスしても、その方法を知らない人が多いです。そこで、Streamlitを使用して、研究室内のPCのCPU使用率とGPU使用率を一目で確認できるウェブサイトを作成しました。
仕組み
Pythonのparamikoライブラリを利用してSSH接続でログインし、あらかじめ登録しておいたコマンドでCPUとGPUの使用率を取得する仕組みです。取得した情報はStreamlitを通じて表示されます。
使用コマンド
以下のコマンドを使用してCPUとGPUの使用率を一括で取得しました。awkを含むこれらのコマンドは、実は私も完全には理解していませんが、ChatGPTのアドバイスを得て作成しました。
COM_USE_CPU = "top -b -n 1 | grep 'Cpu(s)' | awk '{print $2+$4}'"
COM_USE_GPU = "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader"
ログイン情報
ログイン情報は以下の形式で保存しています。
host_user = {
PC名: ['ホストIP', 'ユーザ名', 'パスワード'],
}
メインとなるクラスを定義
Clientクラスを定義して、認証とデータ取得を担当します。このクラスのインスタンスはst.session_stateに保存され、使用率の更新時に再認証が不要になるように設計しました。
class RemoteClient:
def __init__(self):
self.cpu_outs = {}
self.gpu_outs = {}
self.auth_client()
def auth_client(self):
self.clients = {}
for key in host_user.keys():
with paramiko.SSHClient() as client:
HOSTNAME = host_user[key][0]
USERNAME = host_user[key][1]
PASSWORD = host_user[key][2]
# SSH接続
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# パスワード認証認証方式
client.connect(hostname=HOSTNAME, port=22,
username=USERNAME, password=PASSWORD)
self.clients[key] = client
def get_useing_cpu(self):
for key, client in self.clients.items():
# CPUの使用率を確認する
res_cpu = client.exec_command(COM_USE_CPU)
# 出力結果をきれいにする
out = float([i for i in res_cpu[1]][0].replace("\n", ""))
self.cpu_outs[key] = out
return self.cpu_outs.copy()
def get_useing_gpu(self):
# GPUがあればその利用率も取得
# 事前にkey設定しておく
for key in self.gpu_outs.keys():
res_gpu = self.clients[key].exec_command(COM_USE_GPU)
out = [i.replace("\n", "").replace(" ","") for i in res_gpu[1]]
self.gpu_outs[key] = out
return self.gpu_outs.copy()
Webサイト部分
Streamlitを用いて、読み込み中にスピナーを表示し、認証と情報取得、表示を行います。使用率の更新はボタンを押すことで行われます。
# 一度認証したらそれ以降しないようにする
with st.spinner("Loading..."):
if 'client' not in st.session_state:
rc = RemoteClient()
st.session_state["client"] = rc
else:
rc = st.session_state["client"]
cpu_outs = rc.get_useing_cpu()
gpu_outs = rc.get_useing_gpu()
# 記録したものをstreamlitで表示
st.markdown("# CPU使用率")
for item in cpu_outs.items():
st.markdown(f"- {item[0]}: CPUの使用率 {item[1]}%")
st.markdown("# GPU使用率")
for item in gpu_outs.items():
st.markdown(f"- {item[0]}: GPUの使用率 {item[1]}")
st.button("更新")
終わりに
このシステムを使って実際に日常の作業を効率化できています。グラフィカルな表示ができればさらに良いのですが、現時点で研究室内の用途には十分機能しています。