はじめに
システムの動作が遅くなると、アクティビティモニタやタスクマネージャを起動してリソースの使用状況を確認することが多いと思います。
Pythonのpsutilライブラリを使用すると、これらのチェックを自動化できます。システムの安定性や評価を向上させるために、監視の強化が重要です。
機能と監視する項目
- ログの記録
- レポート作成
- アラート
- CPU、メモリ、ディスク、ネットワークの使用率
- スケジュール設定
環境構築
pip install psutil schedule
venvやpipenvなどで仮想環境を作成するとローカルが汚れにくいです。
コード
import logging
import psutil
import schedule
import time
# ログの記録とレポート作成
def log_message(message):
logging.basicConfig(
filename='system.log',
level=logging.INFO,
format='%(asctime)s - %(message)s'
)
logging.info(message)
# アラート
def alert(message):
print(f'ALERT: {message}')
# ヘルスチェック
def check_cpu_usage(threshold=50):
# CPU使用率の監視
cpu_usage = psutil.cpu_percent(interval=1)
if cpu_usage > threshold:
message = f'CPU使用率が高いです: {cpu_usage}'
log_message(message)
alert(message)
# メモリ使用率の監視
def check_memory_usage(threshold=50):
memory_usage = psutil.virtual_memory().percent
if memory_usage > threshold:
message = f'メモリ使用率が高いです: {memory_usage}'
log_message(message)
alert(message)
# ディスク容量の監視
def check_disk_usage(path='/', threshold=50):
disk_usage = psutil.disk_usage(path).percent
if disk_usage > threshold:
message = f'ディスク使用率が高いです: {disk_usage}'
log_message(message)
alert(message)
# ネットワークの使用量の監視
def check_network_usage(threshold=100 * 1024 * 1024):
network_usage = psutil.net_io_counters().bytes_recv \
+ psutil.net_io_counters().bytes_sent
if network_usage > threshold:
message = f'ネットワーク使用率が高いです:{network_usage:.2f} MB'
log_message(message)
alert(message)
# 監視
def run_health_check():
print('システム監視中...')
log_message('ヘルスチェック中...')
check_cpu_usage()
check_memory_usage()
check_disk_usage()
check_network_usage()
log_message('ヘルスチェック終了')
# 監視のスケジュール設定
schedule.every(1).minutes.do(run_health_check)
while True:
schedule.run_pending()
time.sleep(1)
解説
システム監視に必要なライブラリをインポートします。
import logging
import psutil
import schedule
import time
ログの記録とレポート作成
CPU使用率などヘルスチェックの結果を記録します。
loggingライブラリでsystem.logというファイルにログを記録します。
def log_message(message):
logging.basicConfig(
filename='system.log',
level=logging.INFO,
format='%(asctime)s - %(message)s'
)
logging.info(message)
アラート
CPU使用率など閾値を超えた場合に警告を出します。
def alert(message):
print(f'ALERT: {message}')
ヘルスチェック
それぞれの項目で監視する機能を作成します
CPU使用率の監視
CPU使用率を監視する機能です。
閾値を設定し、その値を超えた時にログの記録をし、警告を出します。
def check_cpu_usage(threshold=50):
cpu_usage = psutil.cpu_percent(interval=1)
if cpu_usage > threshold:
message = f'CPU使用率が高いです: {cpu_usage}'
log_message(message)
alert(message)
CPU使用率はシステム全体のパフォーマンスに関係します。
CPUの使用率が過剰になると、動作の低下、最悪はクラッシュが発生します。
メモリ使用率の監視
CPUと同様にメモリ使用率を監視する機能です。
def check_memory_usage(threshold=50):
memory_usage = psutil.virtual_memory().percent
if memory_usage > threshold:
message = f'メモリ使用率が高いです: {memory_usage}'
log_message(message)
alert(message)
メモリ使用率を監視することでメモリリークやリソースを大量に使用するリソースを検出します。
こちらも動作の低下やクラッシュなどの発生に起因します。
ディスク使用率の監視
指定したパスのディスク使用率を監視する機能です。
def check_disk_usage(path='/', threshold=50):
disk_usage = psutil.disk_usage(path).percent
if disk_usage > threshold:
message = f'ディスク使用率が高いです: {disk_usage}'
log_message(message)
alert(message)
ディスク使用率の監視でリソースの枯渇を事前に検知します。
この監視で、特定のパスに十分なストレージ容量があることを確認します。
ネットワーク使用率の監視
閾値はバイト数です。
受信と送信したバイト数を合計して、閾値を超えるとログを記録しアラートを出します。
def check_network_usage(threshold=100 * 1024 * 1024):
network_usage = psutil.net_io_counters().bytes_recv \
+ psutil.net_io_counters().bytes_sent
if network_usage > threshold:
message = f'ネットワーク使用率が高いです:{network_usage:.2f} MB'
log_message(message)
alert(message)
監視機能
前述で作成したそれぞれのヘルスチェック機能を呼び出します。
def run_health_check():
print('システム監視中...')
log_message('ヘルスチェック中...')
check_cpu_usage()
check_memory_usage()
check_disk_usage()
check_network_usage()
log_message('ヘルスチェック終了')
監視のスケジュール設定
scheduleライブラリを使用して、監視機能を自動で実行するようにします。
every()関数で実行間隔を設定します
schedule.every(1).minutes.do(run_health_check)
システム監視を繰り返し実行するように設定します。
while True:
schedule.run_pending()
time.sleep(1)
おわりに
今回はPythonを使用してシステム監視を自動化する方法を紹介しました。
このコードは簡易的なもので、アラートはコンソールに表示されますが、実際の運用ではメールやSlackなどの通知ツールと組み合わせるとより実用的です。
備考
logging.basicConfig()はコードの最初で1度実行すればいいので関数化して何回も実行する必要はないですが、今回分かりやすく関数型で書いています。
logging.basicConfig(
filename='system.log',
level=logging.INFO,
format='%(asctime)s - %(message)s'
)
def log_message(message):
logging.info(message)