您好,欢迎访问一九零五行业门户网

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])
其它类似信息

推荐信息