Pythonでシステム監視

お世話になっております。

システムというものは、単一のプログラムのみで完結するものではなく、様々なプロセスやサービスが協調して動作することによって、ようやくシステムとしての役目を果たすことができます。例えば、簡単なWebアプリケーションであっても、Webサーバーが動作していなければ、ブラウザからアクセスしても何も表示されません。
今回は、Pythontkinterを使ってサービスの状態を監視するツールを作りました。定周期でWindowsのcsコマンドを実行し、画面を更新します。ローカルのサービスであれば、ボタンを操作することで開始/停止することもできます。自分用のツールとしては、とりあえず使えるかな、といったところです。
今後も暇があれば、機能を追加しようと思います。

以下、コードです。

import tkinter
import os
import threading
import time
import re

class ScFrame(tkinter.Frame):
  INTERVAL_MSEC = 3000  #  Update interval
  def __init__(self, service_name, server_name, master=None):
    tkinter.Frame.__init__(self, master)

    self._command = ScCommand(service_name, server_name)
    self._event = threading.Event()
    self._t = threading.Thread(target=self.periodical_update)
    self._t.start()
    # setup components
    self._init_components()
    self.pack()

  def _init_components(self):
    # label
    self._label = tkinter.Label(self)
    self._label['text'] = str(self._command)
    self._label['font'] = ('Courier', 9)
    self._label['relief'] = 'solid'
    self._label['bd'] = '1'
    self._label.pack({'side': 'left'})
    # button
    self._button = tkinter.Button(self)
    self._button['text'] = 'switch'
    self._button['command'] = self.button_click
    self._button.pack({'side': 'left'})

  def periodical_update(self):
    self._command.execute()
    self._label['text'] = str(self._command)
    if self._command.is_running():
      self._label['bg'] = 'green'
    else:
      self._label['bg'] = 'red'

    if not self._event.isSet():
      self.master.after(ScFrame.INTERVAL_MSEC, self.periodical_update)
    else:
      self.event.clear()

  def button_click(self):
    if self._command.is_running():
      self._command.stop()
    else:
      self._command.start()

  def quit(self):
    self._event.set()
    self._event.wait()


class ScCommand(object):
  command_text = 'sc {0._server_name} query {0._service_name}'
  command_text_stop = 'sc {0._server_name} stop {0._service_name}'
  command_text_start = 'sc {0._server_name} start {0._service_name}'

  display_format = '{0._server_name: <13}, {0._service_name: <20}, {0._status: <18}'

  def __init__(self, service_name, server_name):
    self._service_name = service_name
    self._server_name = '' if server_name == None else r'\\' + server_name
    self._status = 'UNKNOWN'

  def execute(self):
    pipe = os.popen(ScCommand.command_text.format(self))
    result_text = pipe.read()
    pipe.close()
    m = re.search('STATE\s*:\s*[^\s]*\s*([^\s]*)', result_text)
    self._status = m.group(1)

  def is_running(self):
    return 'RUNNING' == self._status

  def stop(self):
    command = ScCommand.command_text_stop.format(self)
    os.system(command)

  def start(self):
    command = ScCommand.command_text_start.format(self)
    os.system(command)

  def __str__(self):
    return ScCommand.display_format.format(self)


if __name__ == '__main__':
  root = tkinter.Tk()
  ScFrame('W32Time', '127.0.0.1', master=root).pack({'side': 'top'})
  ScFrame('Tomcat5', '127.0.0.1', master=root).pack({'side': 'top'})
  root.mainloop()

以上