Pythonを活用したLinuxシステム監視:ログ、ディスク、CPU利用率の分析
現代のITインフラにおいて、Linuxサーバーは多くの企業や開発チームにとって不可欠な基盤です。サーバーの安定稼働とパフォーマンス維持のためには、効果的な監視と管理が欠かせません。本稿では、Python言語を活用し、ログの監視、ディスク使用量の評価、そしてCPU負荷の分析を行う方法について解説します。
ログファイルのリアルタイム監視
ログファイルは、システムの状態を把握するための重要な情報源です。これらを継続的に監視することで、潜在的な問題を早期に特定し、障害発生を未然に防ぐことができます。Pythonでは、ログ処理に便利なライブラリがいくつか存在しますが、ここではリアルタイム監視に特化したwatchdogを紹介します。
まずは、watchdogライブラリをインストールします。
pip install watchdog
次に、以下のPythonスクリプトを用いて、特定のログファイルの変更をリアルタイムで監視する例を示します。このスクリプトは、指定したログファイルに変更があった場合に、そのイベントをコンソールに出力します。
import time
import os
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class LogFileActivityHandler(FileSystemEventHandler):
"""指定されたログファイルの変更を処理するハンドラ。"""
def __init__(self, target_log_path):
super().__init__()
self.target_log_path = os.path.abspath(target_log_path)
def on_modified(self, event):
"""ファイルが変更されたときに呼び出される。"""
if not event.is_directory and os.path.abspath(event.src_path) == self.target_log_path:
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] '{os.path.basename(self.target_log_path)}' に変更を検出。", file=sys.stdout)
# ここでログ内容の差分を読み込んだり、通知を送ったりする処理を追加可能
if __name__ == "__main__":
monitored_log_file = '/var/log/syslog' # 監視対象のログファイル (例: Debian/Ubuntu)
# RHEL/CentOS系では '/var/log/messages' など、環境に応じてパスを調整してください。
if not os.path.exists(monitored_log_file):
print(f"エラー: 監視対象のログファイル '{monitored_log_file}' が見つかりません。", file=sys.stderr)
print("適切なログファイルのパスを設定してください。")
sys.exit(1)
# watchdogはファイル自体ではなく、ファイルを含むディレクトリのイベントを監視するため、親ディレクトリを指定します。
log_parent_directory = os.path.dirname(monitored_log_file)
if not log_parent_directory: # ルートディレクトリ直下のファイルの場合
log_parent_directory = '/'
event_processor = LogFileActivityHandler(monitored_log_file)
monitor_observer = Observer()
monitor_observer.schedule(event_processor, path=log_parent_directory, recursive=False)
monitor_observer.start()
print(f"'{monitored_log_file}' の変更監視を開始しました。Ctrl+Cで終了します。")
try:
while True:
time.sleep(3) # ポーリング間隔
except KeyboardInterrupt:
print("\n監視を停止しています...")
monitor_observer.stop()
monitor_observer.join()
print("監視が終了しました。")
このスクリプトを実行すると、指定されたログファイルに書き込みが行われるたびに通知が表示されます。実際の運用では、検出した変更内容を解析し、特定のキーワードが含まれていればアラートを発報するといった拡張が考えられます。
ディスク使用状況の確認と分析
ディスク容量は、サーバーが安定して動作するための基盤となるリソースの一つです。容量が枯渇すると、サービスの停止やパフォーマンスの大幅な低下を招く可能性があります。Pythonのpsutilライブラリは、システムの様々なリソース情報を取得でき、ディスク使用状況の監視にも非常に有効です。
まずは、psutilライブラリをインストールします。
pip install psutil
次に、ルートディレクトリ(/)のディスク使用状況を詳細に表示するPythonスクリプトの例を示します。
import psutil
import sys
def report_system_disk_status(mount_point='/'):
"""指定されたマウントポイントのディスク使用状況を報告する。"""
try:
disk_stats = psutil.disk_usage(mount_point)
total_gb = disk_stats.total / (1024**3)
used_gb = disk_stats.used / (1024**3)
free_gb = disk_stats.free / (1024**3)
utilization_percent = disk_stats.percent
print(f"--- ディスク使用状況 ({mount_point}) ---", file=sys.stdout)
print(f" 総容量: {total_gb:.2f} GB", file=sys.stdout)
print(f" 使用済み: {used_gb:.2f} GB", file=sys.stdout)
print(f" 空き容量: {free_gb:.2f} GB", file=sys.stdout)
print(f" 使用率: {utilization_percent:.1f}%", file=sys.stdout)
print("-------------------------------", file=sys.stdout)
# 例: 使用率が90%を超えたら警告メッセージを出力
if utilization_percent > 90:
print(f"警告: ディスク使用率が {utilization_percent:.1f}% と非常に高いです!", file=sys.stderr)
except FileNotFoundError:
print(f"エラー: マウントポイント '{mount_point}' が見つかりません。", file=sys.stderr)
except Exception as e:
print(f"ディスク使用状況の取得中にエラーが発生しました: {e}", file=sys.stderr)
if __name__ == "__main__":
report_system_disk_status('/')
# 別のパーティションを監視したい場合は、引数を変更してください
# report_system_disk_status('/home')
このスクリプトは、指定されたマウントポイントの総容量、使用済み容量、空き容量、および使用率を分かりやすく表示します。また、使用率が一定の閾値を超えた場合に警告メッセージを出力する機能も含まれています。
CPU負荷の分析
CPU負荷は、サーバー全体のパフォーマンスを測る上で極めて重要な指標です。高いCPU負荷は、サービスの応答速度の低下や、最悪の場合、システムの停止を引き起こす可能性があります。psutilライブラリは、CPUの利用状況を把握するためにも活用できます。
以下のPythonスクリプトは、一定間隔で複数回CPU使用率をサンプリングし、その平均値を算出・表示する例です。
import psutil
import time
import sys
def analyze_cpu_utilization(sample_count=5, sample_interval_sec=2):
"""
一定回数CPU使用率をサンプリングし、その平均値を分析する。
Args:
sample_count (int): サンプリング回数。
sample_interval_sec (int): 各サンプリング間の待機時間(秒)。
"""
print(f"--- CPU使用率の分析 ({sample_interval_sec}秒間隔で{sample_count}回サンプリング) ---", file=sys.stdout)
cpu_util_history = []
# psutil.cpu_percentの初回呼び出しは0%を返すため、一度ダミーで呼び出してクリアする
psutil.cpu_percent(interval=None)
time.sleep(1) # 最初のデータ取得のために少し待つ
try:
for i in range(sample_count):
current_cpu_usage = psutil.cpu_percent(interval=None) # interval=Noneで非ブロッキング
cpu_util_history.append(current_cpu_usage)
print(f" サンプル {i+1}: {current_cpu_usage:.1f}%", file=sys.stdout)
if i < sample_count - 1:
time.sleep(sample_interval_sec)
except KeyboardInterrupt:
print("\nCPU分析を中断しました。", file=sys.stdout)
sys.exit(0)
except Exception as e:
print(f"CPU使用率の取得中にエラーが発生しました: {e}", file=sys.stderr)
sys.exit(1)
if cpu_util_history:
avg_cpu_usage = sum(cpu_util_history) / len(cpu_util_history)
print(f"---------------------------------", file=sys.stdout)
print(f" 平均CPU使用率: {avg_cpu_usage:.1f}%", file=sys.stdout)
if avg_cpu_usage > 70: # 閾値設定の例
print(" 警告: CPU使用率が平均的に高い状態です。", file=sys.stderr)
else:
print("CPU使用率のデータが取得できませんでした。", file=sys.stdout)
print("---------------------------------", file=sys.stdout)
if __name__ == "__main__":
analyze_cpu_utilization(sample_count=6, sample_interval_sec=3)
このスクリプトは、設定された回数と間隔でCPU使用率を計測し、その平均値を計算します。これにより、単一時点の負荷だけでなく、一定期間のトレンドを把握することが可能になります。平均使用率が設定した閾値を超えた場合には、警告を表示します。