Python写的服务监控程序实例


Posted in Python onJanuary 31, 2015

前言:

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"]) 
Python 相关文章推荐
详细分析python3的reduce函数
Dec 05 Python
python实现画圆功能
Jan 25 Python
django ajax json的实例代码
May 29 Python
Python实现全排列的打印
Aug 18 Python
python利用tkinter实现屏保
Jul 30 Python
Windows平台Python编程必会模块之pywin32介绍
Oct 01 Python
python中dict()的高级用法实现
Nov 13 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
Feb 09 Python
python matplotlib 绘图 和 dpi对应关系详解
Mar 14 Python
Python过滤序列元素的方法
Jul 31 Python
python 解决selenium 中的 .clear()方法失效问题
Sep 01 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
Mar 04 Python
用python 制作图片转pdf工具
Jan 30 #Python
Python是编译运行的验证方法
Jan 30 #Python
Python的类实例属性访问规则探讨
Jan 30 #Python
Python中的作用域规则详解
Jan 30 #Python
Python中使用Boolean操作符做真值测试实例
Jan 30 #Python
Python中的zip函数使用示例
Jan 29 #Python
Python的另外几种语言实现
Jan 29 #Python
You might like
php中常用编辑器推荐
2007/01/02 PHP
Apache中php.ini的设置方法
2013/02/28 PHP
关于使用key/value数据库redis和TTSERVER的心得体会
2013/06/28 PHP
百度ping方法使用示例 自动ping百度
2014/01/26 PHP
php+jQuery+Ajax简单实现页面异步刷新
2016/08/08 PHP
Laravel框架实现定时发布任务的方法
2018/08/16 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
2019/11/26 PHP
如何用javascript判断录入的日期是否合法
2007/01/08 Javascript
js调用AJAX时Get和post的乱码解决方法
2013/06/04 Javascript
js遍历、动态的添加数据的小例子
2013/06/22 Javascript
js获取location.href的参数实例代码
2013/08/02 Javascript
JS和Jquery获取和修改label的值的示例代码
2014/01/15 Javascript
jQuery对指定元素中指定字符串进行替换的方法
2015/03/17 Javascript
基于jQuery实现歌词滚动版音乐播放器的代码
2016/09/17 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
jQuery.parseHTML() 函数详解
2017/01/09 Javascript
jQuery图片加载失败替换默认图片方法汇总
2017/11/29 jQuery
vue与bootstrap实现简单用户信息添加删除功能
2019/02/15 Javascript
layui table 列宽百分比显示的实现方法
2019/09/28 Javascript
[00:50]2014DOTA2国际邀请赛 NEWBEE战队回顾
2014/08/01 DOTA
Python2.x和3.x下maketrans与translate函数使用上的不同
2015/04/13 Python
利用Python的装饰器解决Bottle框架中用户验证问题
2015/04/24 Python
用python制作游戏外挂
2018/01/04 Python
Python下opencv图像阈值处理的使用笔记
2019/08/04 Python
Python破解BiliBili滑块验证码的思路详解(完美避开人机识别)
2020/02/17 Python
在keras下实现多个模型的融合方式
2020/05/23 Python
PyCharm 光标变成黑块的解决方式
2021/02/06 Python
css3实现的多级渐变下拉菜单导航效果代码
2015/08/31 HTML / CSS
html5指南-6.如何创建离线web应用程序实现离线访问
2013/01/07 HTML / CSS
德尔福集团DELPHI的笔试题
2012/02/22 面试题
艺校音乐专业自我鉴定范文
2014/03/01 职场文书
健康家庭事迹材料
2014/05/02 职场文书
导游词之湖北武当山
2019/09/23 职场文书
Python绘制分类图的方法
2021/04/20 Python
java泛型通配符详解
2021/07/25 Java/Android
sql server删除前1000行数据的方法实例
2021/08/30 SQL Server