「午前3時のサーバーダウン」という悪夢
深夜に鳴り響くアラートは、すべてのDevOpsエンジニアにとっての悪夢です。かつて私も、メモリリークを起こしたPythonスクリプトが16GB의 RAMを使い果たし、全サービスを停止させてしまったために徹夜したことがあります。上司から催促される中、必死に手動でログを確認した経験はありませんか?
実際、topやhtopを使うだけでは根本的な解決にはなりません。大規模なシステムを管理する場合、惨事が発生する前にエラーを検知し、ログを記録し、リソースを解放する自動化メカニズムが必要です。それが、手動コマンドではなくプログラミングによる解決策が必要な理由です。
なぜ従来のシェルコマンド呼び出しをやめたのか?
キャリアの初期、私はよくsubprocessを使ってfree -mやdf -hを呼び出し、正規表現(Regex)でデータを抽出していました。しかし、この方法は非常にリスクが高いです。UbuntuからCentOSやWindowsに移行しただけで、出力フォーマットの違いにより、それらのスクリプトは即座に「崩壊」してしまいます。
また、RAM情報を取得するためだけに新しいプロセスをフォークするのも、リソースの無駄です。psutil (process and system utilities) は、この混乱を解決するために生まれました。Linux、WindowsからmacOSまで、あらゆるプラットフォームでスムーズに動作する純粋なPython APIを提供します。
psutilの実装:基本から応用まで
このライブラリを使えば、基盤となるOSを気にすることなく、あらゆるハードウェアの統計情報を取得できます。以下に、実際のプロジェクトでの活用方法を紹介します。
1. クイックインストール
ターミナルを開き、pipでインストールします。システムをクリーンに保つために、仮想環境(venv)の使用をお勧めします:
pip install psutil
2. CPU監視:0.0という数値に騙されないで
よくある間違いは、引数を渡さずにpsutil.cpu_percent()を呼び出すことです。ライブラリに使用率を比較するための時間間隔がないため、返り値は通常0.0になってしまいます。
import psutil
# 誤り:通常は0.0が返される
print(f"CPU: {psutil.cpu_percent()}%")
# 正解:平均値を取得するために1秒待機する
print(f"実際のCPU使用率: {psutil.cpu_percent(interval=1)}%")
# 各コアごとの負荷を確認する
print(f"各コアの詳細: {psutil.cpu_percent(interval=1, percpu=True)}")
素早い更新が必要なダッシュボードでは、精度とレスポンス速度のバランスをとるために、私はよくinterval=0.1を設定します。
3. RAM管理:「Free」ではなく「Available」を見る
Linuxにおいて、RAMの「Free」が少ないことは、必ずしもメモリ不足を意味しません。システムは高速化のためにRAMをキャッシュとして使用することが多いためです。psutilを使えば、アプリケーションが追加で占有できる実際の容量である「Available」を計算できます。
mem = psutil.virtual_memory()
print(f"合計RAM: {mem.total / (1024**3):.2f} GB")
print(f"使用率: {mem.percent}%")
if mem.percent > 90:
print("危険:RAMが不足しています!")
4. ディスクチェック:ディスクフルによる惨劇を防ぐ
ログファイルの肥大化によるデータベースのクラッシュは、非常に「初歩的」でありながら頻発するミスです。数行のコードでディスク容量のチェックを自動化できます:
disk = psutil.disk_usage('/')
# 空き容量が5GB未満の場合に警告
if disk.free < (5 * 1024**3):
print(f"警告:ディスクの空き容量が残り {disk.free / (1024**3):.2f} GB です!")
5. プロセス管理:最も価値のある機能
こここそが、psutilの真骨頂です。暴走しているプロセスを特定し、監視し、「成敗」することができます。私はよく、実行中のスクリプト自体を制御するためにこれを使用します。スクリプトが2GB以上のRAMを消費した場合、OSに強制終了されるのを待つのではなく、安全に自ら終了するようにします。
Case study: 自動システムクリーニング「キラー」スクリプト
以下は、私がワーカーサーバーを保護するために使用しているコードです。Pythonプロセスをスキャンし、500MB以上のRAMを消費しているものを即座に終了させます。
import psutil
def auto_cleanup(keyword, limit_mb):
for proc in psutil.process_iter(['pid', 'name', 'memory_info']):
try:
# プロセス名にキーワードが含まれているか確認
if keyword.lower() in proc.info['name'].lower():
usage = proc.info['memory_info'].rss / (1024 * 1024)
if usage > limit_mb:
print(f"PID {proc.info['pid']} が {usage:.1f}MB 消費しているため終了させます")
psutil.Process(proc.info['pid']).terminate()
except (psutil.NoSuchProcess, psutil.AccessDenied):
# プロセスが存在しないかアクセス権限がない場合はスキップ
continue
if __name__ == "__main__":
auto_cleanup("python", 500)
実務経験からの結び
Pythonで独自の監視ツールを構築することは、究極の柔軟性をもたらします。基本的な機能のために、サードパーティのソリューションに数千ドルを費やす必要はありません。psutilさえあれば、アラートをTelegramに飛ばしたり、トラブル発生時にサービスを自動再起動したりできます。今日からシステムに統合して、より質の高い睡眠を手に入れましょう。

