Python写的服务监控程序实例_python

前言:

Redhat下安装Python2.7

rhel6.4自带的是2.6, 发现有的机器是python2.4。 到python网站下载源代码,解压到Redhat上,然后运行下面的命令:

复制代码 代码如下:

# ./configure --prefix=/usr/local/python27
# make
# make install

这样安装之后默认不会启用Python2.7,需要使用/usr/local/python27/bin/python2.7调用新版本的python。

而下面的安装方式会直接接管现有的python

复制代码 代码如下:

# ./configure
# make
# make install

开始:

服务子进程被监控主进程创建并监控,当子进程异常关闭,主进程可以再次启动之。使用了python的subprocess模块。就这个简单的代码,居然互联网上没有现成可用的例子。没办法,我写好了贡献出来吧。

首先是主进程代码:service_mgr.py

复制代码 代码如下:

#!/usr/bin/python 
#-*- coding: UTF-8 -*- 
# cheungmine 
# stdin、stdout和stderr分别表示子程序的标准输入、标准输出和标准错误。 
#  
# 可选的值有: 
#   subprocess.PIPE - 表示需要创建一个新的管道. 
#   一个有效的文件描述符(其实是个正整数) 
#   一个文件对象 
#   None - 不会做任何重定向工作,子进程的文件描述符会继承父进程的. 
#  
# stderr的值还可以是STDOUT, 表示子进程的标准错误也输出到标准输出. 
#  
# subprocess.PIPE 
# 一个可以被用于Popen的stdin、stdout和stderr 3个参数的特输值,表示需要创建一个新的管道. 
#  
# subprocess.STDOUT 
# 一个可以被用于Popen的stderr参数的特输值,表示子程序的标准错误汇合到标准输出. 
################################################################################ 
import os 
import sys 
import getopt 
 
import time 
import datetime 
 
import codecs 
 
import optparse 
import ConfigParser 
 
import signal 
import subprocess 
import select 
 
# logging 
# require python2.6.6 and later 
import logging   
from logging.handlers import RotatingFileHandler 
 
## log settings: SHOULD BE CONFIGURED BY config 
LOG_PATH_FILE = "./my_service_mgr.log" 
LOG_MODE = 'a' 
LOG_MAX_SIZE = 4*1024*1024 # 4M per file 
LOG_MAX_FILES = 4          # 4 Files: my_service_mgr.log.1, printmy_service_mgrlog.2, ...   
LOG_LEVEL = logging.DEBUG   
 
LOG_FORMAT = "%(asctime)s %(levelname)-10s[%(filename)s:%(lineno)d(%(funcName)s)] %(message)s"   
 
handler = RotatingFileHandler(LOG_PATH_FILE, LOG_MODE, LOG_MAX_SIZE, LOG_MAX_FILES) 
formatter = logging.Formatter(LOG_FORMAT) 
handler.setFormatter(formatter) 
 
Logger = logging.getLogger() 
Logger.setLevel(LOG_LEVEL) 
Logger.addHandler(handler)  
 
# color output 

pid = os.getpid()  
 
def print_error(s): 
    print '\033[31m[%d: ERROR] %s\033[31;m' % (pid, s) 
 
def print_info(s): 
    print '\033[32m[%d: INFO] %s\033[32;m' % (pid, s) 
 
def print_warning(s): 
    print '\033[33m[%d: WARNING] %s\033[33;m' % (pid, s) 
 
 
def start_child_proc(command, merged): 
    try: 
        if command is None: 
            raise OSError, "Invalid command" 
 
        child = None 
 
        if merged is True: 
            # merge stdout and stderr 
            child = subprocess.Popen(command, 
                stderr=subprocess.STDOUT, # 表示子进程的标准错误也输出到标准输出 
                stdout=subprocess.PIPE    # 表示需要创建一个新的管道 
            ) 
        else: 
            # DO NOT merge stdout and stderr 
            child = subprocess.Popen(command, 
                stderr=subprocess.PIPE, 
                stdout=subprocess.PIPE) 
 
        return child 
 
    except subprocess.CalledProcessError: 
        pass # handle errors in the called executable 
    except OSError: 
        pass # executable not found 
 
    raise OSError, "Failed to run command!" 
 
 
def run_forever(command): 
    print_info("start child process with command: " + ' '.join(command)) 
    Logger.info("start child process with command: " + ' '.join(command)) 
 
    merged = False 
    child = start_child_proc(command, merged) 
 
    line = '' 
    errln = '' 
 
    failover = 0 
 
    while True: 
        while child.poll() != None: 
            failover = failover + 1 
            print_warning("child process shutdown with return code: " + str(child.returncode))            
            Logger.critical("child process shutdown with return code: " + str(child.returncode)) 
 
            print_warning("restart child process again, times=%d" % failover) 
            Logger.info("restart child process again, times=%d" % failover) 
            child = start_child_proc(command, merged) 
 
        # read child process stdout and log it 
        ch = child.stdout.read(1) 
        if ch != '' and ch != '\n': 
            line += ch 
        if ch == '\n': 
            print_info(line) 
            line = '' 
 
        if merged is not True: 
            # read child process stderr and log it 
            ch = child.stderr.read(1) 
            if ch != '' and ch != '\n': 
                errln += ch 
            if ch == '\n': 
                Logger.info(errln) 
                print_error(errln) 
                errln = '' 
 
    Logger.exception("!!!should never run to this!!!")   
 
 
if __name__ == "__main__": 
    run_forever(["python", "./testpipe.py"]) 

然后是子进程代码:testpipe.py

复制代码 代码如下:

#!/usr/bin/python 
#-*- coding: UTF-8 -*- 
# cheungmine 
# 模拟一个woker进程,10秒挂掉 
import os 
import sys 
 
import time 
import random 
 
cnt = 10 
 
while cnt >= 0: 
    time.sleep(0.5) 
    sys.stdout.write("OUT: %s\n" % str(random.randint(1, 100000))) 
    sys.stdout.flush() 
 
    time.sleep(0.5) 
    sys.stderr.write("ERR: %s\n" % str(random.randint(1, 100000))) 
    sys.stderr.flush() 
 
    #print str(cnt) 
    #sys.stdout.flush() 
    cnt = cnt - 1 
 
sys.exit(-1) 

Linux上运行很简单:

复制代码 代码如下:

$ python service_mgr.py

Windows上以后台进程运行:

复制代码 代码如下:

> start pythonw service_mgr.py

代码中需要修改:

复制代码 代码如下:

run_forever(["python", "testpipe.py"]) 

时间: 2024-09-11 17:57:51

Python写的服务监控程序实例_python的相关文章

python 调用HBase的简单实例_python

新来的一个工程师不懂HBase,java不熟,python还行,我建议他那可以考虑用HBase的thrift调用,完成目前的工作. 首先,安装thrift 下载thrift,这里,我用的是thrift-0.7.0-dev.tar.gz 这个版本 tar xzf thrift-0.7.0-dev.tar.gz cd thrift-0.7.0-dev sudo ./configure --with-cpp=no --with-ruby=no sudo make sudo make install 然

理解Python中的类与实例_python

面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的"对象",每个对象都拥有相同的方法,但各自的数据可能不同. 仍以Student类为例,在Python中,定义类是通过class关键字: class Student(object): pass class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再

python中MySQLdb模块用法实例_python

本文实例讲述了python中MySQLdb模块用法.分享给大家供大家参考.具体用法分析如下: MySQLdb其实有点像php或asp中连接数据库的一个模式了,只是MySQLdb是针对mysql连接了接口,我们可以在python中连接MySQLdb来实现数据的各种操作. python连接mysql的方案有oursql.PyMySQL. myconnpy.MySQL Connector 等,不过本篇要说的确是另外一个类库MySQLdb,MySQLdb 是用于Python链接Mysql数据库的接口,它

python模块restful使用方法实例_python

RESTful架构,目前是比较流行的一种互联网软件架构.REST,即Representational State Transfer的缩写. 说白点就是网站即软件,再白点就是一个服务软件支持http的四种方法: GET用来获取资源,POST用来新建资源.更新资源,PUT用来更新资源,DELETE用来删除资源. 并对外提供一个或多个URI,每个URI对应一个资源:客户端通过URI配合上面的方法就可以和服务 段的软件交互.客户端主要是浏览器,使用restful框架的软件对http的支持也为了web应用

Python读写Excel文件的实例_python

最近由于经常要用到Excel,需要根据Excel表格中的内容对一些apk进行处理,手动处理很麻烦,于是决定写脚本来处理.首先贴出网上找来的读写Excel的脚本.1.读取Excel(需要安装xlrd): #-*- coding: utf8 -*- import xlrd fname = "reflect.xls" bk = xlrd.open_workbook(fname) shxrange = range(bk.nsheets) try: sh = bk.sheet_by_name(&

Python守护进程(daemon)代码实例_python

# -*-coding:utf-8-*- import sys, os '''将当前进程fork为一个守护进程 注意:如果你的守护进程是由inetd启动的,不要这样做!inetd完成了 所有需要做的事情,包括重定向标准文件描述符,需要做的事情只有 chdir() 和 umask()了 ''' def daemonize(stdin='/dev/null',stdout= '/dev/null', stderr= 'dev/null'): '''Fork当前进程为守护进程,重定向标准文件描述符 (

Python中的并发编程实例_python

一.简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执行,这个控制流被称为该进程的主线程.在任何给定的时刻,一个程序只做一件事情. 一个程序可以通过Python库函数中的os或subprocess模块创建新进程(例如os.fork()或是subprocess.Popen()).然而,这些被称为子进程的进程却是独立运行的,它们有各自独立的系统状态以及

python批量提交沙箱问题实例_python

本文实例讲述了python批量提交沙箱问题,分享给大家供大家参考.具体方法如下: 出现的问题如下: 1. Popen的使用,在linux下参数用列表传,不要用字符串传   否则可能会有"OSErrorror: [Errno 2] No such file or directory"错误 2. 列表要拷贝用 shutil模块中  不然会连续append..提交完第一个样本后,后面的提交参数就错了. 代码如下: import os from subprocess import Popen

Python采集腾讯新闻实例_python

目标是把腾讯新闻主页上所有新闻爬取下来,获得每一篇新闻的名称.时间.来源以及正文. 接下来分解目标,一步一步地做. 步骤1:将主页上所有链接爬取出来,写到文件里. python在获取html方面十分方便,寥寥数行代码就可以实现我们需要的功能. 复制代码 代码如下: def getHtml(url):      page = urllib.urlopen(url)      html = page.read()      page.close()      return html 我们都知道htm