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 相关文章推荐
python strip()函数 介绍
May 24 Python
python中numpy包使用教程之数组和相关操作详解
Jul 30 Python
python正则表达式面试题解答
Apr 28 Python
python基础教程项目四之新闻聚合
Apr 02 Python
Python数据可视化之画图
Jan 15 Python
python二维键值数组生成转json的例子
Dec 06 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
Mar 13 Python
python实现交并比IOU教程
Apr 16 Python
图解Python中深浅copy(通俗易懂)
Sep 03 Python
Python实现自动整理文件的脚本
Dec 17 Python
详解用Python把PDF转为Word方法总结
Apr 27 Python
使用python如何删除同一文件夹下相似的图片
May 07 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容易被忽略而出错陷阱 数字与字符串比较
2011/11/10 PHP
跨浏览器PHP下载文件名中的中文乱码问题解决方法
2015/03/05 PHP
教大家制作简单的php日历
2015/11/17 PHP
php输出控制函数和输出函数生成静态页面
2019/06/27 PHP
jQuery Ajax调用WCF服务详细教程
2015/03/31 Javascript
浅谈Javascript中的12种DOM节点类型
2016/08/19 Javascript
web前端开发upload上传头像js示例代码
2016/10/22 Javascript
Node.js复制文件的方法示例
2016/12/29 Javascript
深入理解Node.js中的进程管理
2017/03/13 Javascript
Bootstrap实现各种进度条样式详解
2017/04/13 Javascript
jQuery实现动态添加、删除按钮及input输入框的方法
2017/04/27 jQuery
微信小程序后台解密用户数据实例详解
2017/06/28 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
2017/08/15 Javascript
js实现页面多个日期时间倒计时效果
2019/06/20 Javascript
jquery插件开发模式实例详解
2019/07/20 jQuery
vue router动态路由设置参数可选问题
2019/08/21 Javascript
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
Python实现的生产者、消费者问题完整实例
2018/05/30 Python
python交互界面的退出方法
2019/02/16 Python
使用python打印十行杨辉三角过程详解
2019/07/10 Python
vim自动补全插件YouCompleteMe(YCM)安装过程解析
2019/10/21 Python
django框架ModelForm组件用法详解
2019/12/11 Python
Pyqt5自适应布局实例
2019/12/13 Python
Python3和PyCharm安装与环境配置【图文教程】
2020/02/14 Python
Pyqt5 关于流式布局和滚动条的综合使用示例代码
2020/03/24 Python
Django 实现将图片转为Base64,然后使用json传输
2020/03/27 Python
使用keras根据层名称来初始化网络
2020/05/21 Python
在pycharm中文件取消用 pytest模式打开的操作
2020/09/01 Python
15款Python编辑器的优缺点,别再问我“选什么编辑器”啦
2020/10/19 Python
CSS3 rgb and rgba(透明色)的使用详解
2020/09/25 HTML / CSS
Notino法国:购买香水和化妆品
2019/04/15 全球购物
移风易俗倡议书
2014/04/15 职场文书
美术指导助理求职信
2014/04/20 职场文书
珍爱生命演讲稿
2014/05/10 职场文书
法人授权委托书范本
2014/09/17 职场文书
Vue-Element-Admin集成自己的接口实现登录跳转
2021/06/23 Vue.js