LoginSignup
21
22

More than 5 years have passed since last update.

サーバーの状態をブラウザから確認できるPythonスクリプト

Last updated at Posted at 2016-06-09

説明

ブラウザからサーバーの状態を監視する。
Pythonの入門書籍を参考にして、それを少し改良して作った。
たいしたものではないですが、せっかく作ったので残しておく。

画面

サーバーで実行すると8000ポートで待ち受ける。
ブラウザで開くとメニューが表示される。

無題.png

コマンドをクリックするとブラウザ上で結果を見れる。

無題2.png

ソースコード

# coding: UTF-8

import BaseHTTPServer, shutil, os
from cStringIO import StringIO

class  MyHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    # 提供するサービスのHTTPパスおよびコマンドラインコマンド

    cmds = { '/free': 'free',
            '/cpuinfo' : 'cat /proc/cpuinfo',
            '/netstat' : 'netstat -anp',
            '/netstat-nlt' : 'netstat -nlt',
            '/uptime' : 'uptime',
            '/vmstat' : 'vmstat',
            '/df' : 'df -h',
            '/sar' : 'sar',
            '/hostname' : 'hostname',
            '/date' : 'date',
            '/ps' : 'ps aux',
            '/iostat' : 'iostat',
            '/pstree' : 'pstree',
            '/ifconfig' : 'ifconfig',
            '/who' : 'who'}

    def do_GET(self):
        # GETリクエストへのサービス

        # レスポンスやコンテンツタイプを指定するためにheadメソッドを呼び出しておく。
        f = self.send_head()

        # ファイルオブジェクトが帰ってきていればレスポンスチェックが通り、200OKなのでボディを作成する。
        # なお今回はGETなので上記のfは使わないで下記のように新しく上書きする。
        if f:
            f = StringIO()

            # マシン名を取得する
            machine = os.popen("hostname").readlines()[0]

            # /ならばインデックスを作成して返すだけ
            if self.path == "/":
                heading = "Select a command to run on %s" % (machine)
                body = self.getMenu()

            # コマンド指定の場合は実際にコマンドを実行して返す。
            else:
                heading = "Execution of ``%s'' on %s" % ( self.cmds[self.path], machine )
                cmd = self.cmds[self.path]
                body = '<a href="/">Main Menu</a><pre>%s</pre>\n' % os.popen(cmd).read()

            f.write("<html><head><title>%s</title></head>\n" % (heading) )
            f.write("<body><h1>%s</h1>\n" % (heading))
            f.write(body)
            f.write("</body></html>\n")
            f.seek(0)
            self.copyfile(f, self.wfile)
            f.close()
        return f

    def do_HEAD(self):
        # HEADリクエストへのサービス
        f = self.send_head()
        if f:
            f.close()

    def send_head(self):
        path = self.path
        if not path in ["/"] + self.cmds.keys():
            head = 'Command "%s" not found. Try one of these:<ul>' % path
            msg = head + self.getMenu()
            self.send_error(404, msg)
            return None
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=UTF-8")
        self.end_headers()
        f = StringIO()
        f.write("A test %s\n" % self.path)
        f.seek(0)
        return f

    def getMenu(self):
        keys = self.cmds.keys()
        keys.sort()
        msg = []
        for k in keys:
            msg.append('<li><a href="%s">%s => %s</a></li>' % (k,k, self.cmds[k]))

        msg.append("</ul>")
        return "\n".join(msg)

    def copyfile(self, source, outputfile):
        shutil.copyfileobj(source, outputfile)

def main(HandlerClass = MyHTTPRequestHandler, ServerClass = BaseHTTPServer.HTTPServer):
    BaseHTTPServer.test(HandlerClass, ServerClass)

if __name__ == '__main__':
    main()
21
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
22