現在、inotify-syncやglancesなど、Python言語で書かれたLinuxシステム監視ツールが数多くあります。 本記事では、Pythonスクリプトを使用してLinuxサーバのCPUメモリネットワーク監視スクリプトを実現する方法を紹介します。
Pythonリリースノート
Pythonは、Guido van Rossumによって開発された、自由に利用できる非常に高レベルのインタプリタ型言語です。理解しやすい構文と強力なオブジェクト指向セマンティクスを持つPythonは、広く利用可能で移植性が高いです。この記事のLinuxサーバーはUbuntu 12.10で、Pythonのバージョンは2.7です。Python 3.0バージョンであれば、構文に若干の違いがあります。また、ここで紹介するPythonはCPythonで、C言語で実装されたPythonインタプリタです。CPythonの他にも、Javaで実装されたJythonや.NETで実装されたIronPythonがあり、Javaプログラムや.NETプログラムとPythonを簡単に統合することができます。CPythonはバイトコードインタープリタであり、プログラムのソースコードは実行前にバイトコードにコンパイルされます。また、他のいくつかの言語と相互作用するための外部関数インターフェイスを持っています。
仕組み:/procファイルシステムに基づいています。
Linux システムは、カーネル・システムをリブートする必要なく、システム実行中にカーネルを変更する非常に優れた方法を管理者に提供します。これは、/proc 仮想ファイル・システムによって実現されます。procファイル仮想システムは、カーネルとカーネルモジュールがプロセスに情報を送信するために使用するメカニズムです。 この擬似ファイルシステムにより、カーネルの内部データ構造との対話、プロセスに関する有用な情報の取得、および実行時の設定の変更が可能になります。他のファイルシステムとは異なり、/proc はハードディスク上ではなくメモリ上に存在します。/proc ファイルシステムが提供する情報は以下の通りです:
- プロセス情報: システム上のどのプロセスも、procのサブディレクトリに同じ名前のプロセスIDを持っており、そこでcmdline、mem、root、stat、statm、statusのような情報を見ることができます。既存のプロセス情報を含む個々のプロセスには、いくつかの専用リンクが用意されており、システム上のどのプロセスも、プロセス情報を指す独立した自己リンクを持ち、プロセスからコマンドライン情報を取得するために使用されます。
- システム情報:CPU使用率、ディスク容量、メモリスワップ、割り込みなど、システム全体の情報を知りたい場合は、/proc/statから取得することもできます。
- CPU情報:/proc/CPUinfoファイルを使用すると、CPUに関する最新の正確な情報を得ることができます。
- ロード情報:/proc/loadavg ファイルにはシステムのロード情報が含まれています。
- システム・メモリ情報:/proc/meminfo ファイルにはシステム・メモリに関する詳細情報が含まれており、物理メモリ量、空きスワップ領域量、空きメモリ量が表示されます。
表1は、/procディレクトリ内の主なファイルの説明です:
表1 /procディレクトリの主なファイルの説明
この記事の以下の例では、Pythonスクリプトを使用して/procディレクトリ内の主要なファイルを読み取り、Linuxサーバーを監視します。
#p#
PythonスクリプトによるLinuxサーバーの監視
- CPUの監視
スクリプト1はCPU1.pyと呼ばれ、CPUに関する情報を取得するために使用されます。
リスト1.CPUの情報を取得:
#!/usr/bin/env Python
from __future__ import print_function
from collections import OrderedDict
import pprint
def CPUinfo():
''' Return the information in /proc/CPUinfo
as a dictionary in the following format:
CPU_info['proc0']={...}
CPU_info['proc1']={...}
'''
CPUinfo=OrderedDict()
procinfo=OrderedDict()
nprocs = 0
with open('/proc/CPUinfo') as f:
for line in f:
if not line.strip():
# end of one processor
CPUinfo['proc%s' % nprocs] = procinfo
nprocsnprocsnprocs=nprocs+1
# Reset
procinfo=OrderedDict()
else:
if len(line.split(':')) == 2:
procinfo[line.split(':')[0].strip()] = line.split(':')[1].strip()
else:
procinfo[line.split(':')[0].strip()] = ''
return CPUinfo
if __name__=='__main__':
CPUinfoCPUinfoCPUinfo = CPUinfo()
for processor in CPUinfo.keys():
print(CPUinfo[processor]['model name'])
簡単なメモとして、リスト 1 は /proc/CPUinfo を読み込み、コアごとに 1 つのディクショナリ(list)を返します。list は角括弧で囲まれた要素の順序付きコレクションで、添え字 0 で始まる配列として使用できます。OrderedDict は辞書のサブクラスで、内容が追加された順番を記憶します。通常のディクショナリは挿入順序を記録しません。反復処理では、ハッシュテーブルに格納されたキーの順序に基づいて値が生成されます。それに対して、OrderedDict では、要素が挿入された順序を記憶し、イテレータを作成するときにその順序を使用します。
CPU1.pyスクリプトはPythonコマンドで実行できます:
# Python CPU1.py
Intel(R) Celeron(R) CPU E3200 @ 2.40GHz
図1.
chmod コマンドを使用して、CPU1.py を直接実行するためのパーミッションを追加することもできます:
#chmod +x CPU1.py
# ./CPU1.py
- システム負荷監視用
スクリプト2 CPU2.pyという名前でシステムの負荷情報を取得します。
リスト2 システムの負荷情報の取得:
#!/usr/bin/env Python
import os
def load_stat():
loadavg = {}
f = open("/proc/loadavg")
con = f.read().split()
f.close()
loadavg['lavg_1']=con[0]
loadavg['lavg_5']=con[1]
loadavg['lavg_15']=con[2]
loadavg['nr']=con[3]
loadavg['last_pid']=con[4]
return loadavg
print "loadavg",load_stat()['lavg_15']
リスト2の簡単な説明: リスト2は、/proc/loadavgの情報を読み込み、import os: importはPythonで、システムが提供するモジュールやカスタムモジュールを含む、さまざまなモジュールをインポートするために使用されます。その基本的な形式は次のとおりです:インポートモジュール名[エイリアスとして]、あなたが唯一のモジュールの内容の一部またはすべてをインポートする必要がある場合は、次の形式で使用することができます:fromモジュール名インポート*対応するモジュールをインポートします。osモジュールosモジュールは、統一されたオペレーティングシステムのインターフェイス機能を提供し、osモジュールは、クロスプラットフォームの操作を実現するように、自動的にnt、posix、特定の関数などの異なるオペレーティングシステムのプラットフォーム間で切り替えることができます。これにより、クロスプラットフォームの操作が可能になります。
CPU1.pyスクリプトはPythonコマンドで実行できます:
# Python CPU2.py
図2.
- メモリー情報取得用
mem.pyというスクリプト3はメモリ使用量の情報を取得するために使用されます。
リスト3 メモリ使用量の取得:
#!/usr/bin/env Python
from __future__ import print_function
from collections import OrderedDict
def meminfo():
''' Return the information in /proc/meminfo
as a dictionary '''
meminfo=OrderedDict()
with open('/proc/meminfo') as f:
for line in f:
meminfo[line.split(':')[0]] = line.split(':')[1].strip()
return meminfo
if __name__=='__main__':
#print(meminfo())
meminfomeminfo = meminfo()
print('Total memory: {0}'.format(meminfo['MemTotal']))
print('Free memory: {0}'.format(meminfo['MemFree']))
リスト3についての簡単なメモ: リスト3は、Pythonの文字列分割メソッドがよく使われるproc/meminfoから情報を読み込んでいます。例えば、非常に長いデータを構造化して保存し、後でデータを取り出して処理できるようにする必要がある場合です。もちろん、jsonを使うこともできます。しかし、データをフィールドに格納し、何らかのマーカーで分割することも可能です。 Pythonはstripを使って文字列の最初の文字を削除し、リスト3はメモリの総量と空き容量を出力します。
#p#
スクリプトmem.pyはPythonコマンドで実行できます。 結果は図3の通りです。
# Python mem.py
図3.
- ネットワークインターフェースの監視
スクリプト4はnet.pyと呼ばれ、ネットワークインターフェースの使用状況を取得するために使用されます。
リスト4 net.pyはネットワークインターフェースの入出力を取得します:
#!/usr/bin/env Python
import time
import sys
if len(sys.argv) > 1:
INTERFACE = sys.argv[1]
else:
INTERFACE = 'eth0'
STATS = []
print 'Interface:',INTERFACE
def rx():
ifstat = open('/proc/net/dev').readlines()
for interface in ifstat:
if INTERFACE in interface:
stat = float(interface.split()[1])
STATS[0:] = [stat]
def tx():
ifstat = open('/proc/net/dev').readlines()
for interface in ifstat:
if INTERFACE in interface:
stat = float(interface.split()[9])
STATS[1:] = [stat]
print 'In Out'
rx()
tx()
while True:
time.sleep(1)
rxstat_o = list(STATS)
rx()
tx()
RX = float(STATS[0])
RX_O = rxstat_o[0]
TX = float(STATS[1])
TX_O = rxstat_o[1]
RX_RATE = round((RX - RX_O)/1024/1024,3)
TX_RATE = round((TX - TX_O)/1024/1024,3)
print RX_RATE ,'MB ',TX_RATE ,'MB'
スクリプトnet.pyをPythonコマンドで実行すると、図4に示すような結果が得られます。
#Python net.py
図4.
Apache サーバのプロセスを監視する Python スクリプト
Apacheサーバープロセスは、Webサービスの停止の結果、システムの理由や異常終了の様々な原因が考えられます。そこで、Pythonのスクリプトファイルを書いています:
リスト5 crtrl.py Apacheサーバープロセスを監視するPythonスクリプト:
#!/usr/bin/env Python
import os, sys, time
while True:
time.sleep(4)
try:
ret = os.popen('ps -C apache -o pid,cmd').readlines()
if len(ret) < 2:
print "apache 进程异常退出, 4 秒后重新启动"
time.sleep(3)
os.system("service apache2 restart")
except:
print "Error", sys.exc_info()[1]
ファイルのパーミッションをexecute属性に設定し、/etc/rc.localに追加します。 このスクリプトはApacheサーバープロセスを自動的にチェックし、異常終了した場合は再起動します。 念のために言っておきますが、リスト5のスクリプトは/proc疑似ファイルシステムに基づいているのではなく、Python独自のモジュールの一部に基づいています。Pythonの組み込みのtimeテンプレートを使用しており、時間を操作するための様々な関数を提供しています。
概要
実際には、Linuxシステム管理者は、使用しているサーバーの特定の条件に従ってLinuxサーバーを監視するためのシンプルで実用的なスクリプトを書くことができます。この記事では、Pythonスクリプトを使用してLinuxサーバーのCPU、システム負荷、メモリ、およびネットワークの使用状況を監視する方法について説明します。





