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中的元类(metaclass)
Feb 14 Python
详解Python的迭代器、生成器以及相关的itertools包
Apr 02 Python
Python连接mysql数据库的正确姿势
Feb 03 Python
使用Nginx+uWsgi实现Python的Django框架站点动静分离
Mar 21 Python
Python操作SQLite数据库的方法详解【导入,创建,游标,增删改查等】
Jul 11 Python
Python列表删除的三种方法代码分享
Oct 31 Python
python XlsxWriter模块创建aexcel表格的实例讲解
May 03 Python
Python 离线工作环境搭建的方法步骤
Jul 29 Python
python文字和unicode/ascll相互转换函数及简单加密解密实现代码
Aug 12 Python
pycharm 对代码做静态检查操作
Jun 09 Python
Python中for后接else的语法使用
May 18 Python
python3 字符串str和bytes相互转换
Mar 23 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
通过5个php实例细致说明传值与传引用的区别
2012/08/08 PHP
解析thinkphp基本配置 convention.php
2013/06/18 PHP
PHP捕获Fatal error错误的方法
2014/06/11 PHP
layui数据表格自定义每页条数limit设置
2019/10/26 PHP
获取JavaScript用户自定义类的类名称的代码
2007/03/08 Javascript
JavaScript 私有成员分析
2009/01/13 Javascript
由document.body和document.documentElement想到的
2009/04/13 Javascript
js 动态选中下拉框
2009/11/26 Javascript
javascript面向对象之二 命名空间
2011/02/08 Javascript
js遍历、动态的添加数据的小例子
2013/06/22 Javascript
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
跟我学习javascript的作用域与作用域链
2015/11/19 Javascript
vue中mint-ui环境搭建详细介绍
2017/04/06 Javascript
VueJs使用Amaze ui调整列表和内容页面
2017/11/30 Javascript
JS实现字符串翻转的方法分析
2018/08/31 Javascript
微信小程序使用蓝牙小插件
2019/09/23 Javascript
基于Vue+ElementUI的省市区地址选择通用组件
2019/11/20 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
Python描述器descriptor详解
2015/02/03 Python
在Django中创建第一个静态视图
2015/07/15 Python
Python中pygame安装方法图文详解
2015/11/11 Python
Python 实现引用其他.py文件中的类和类的方法
2018/04/29 Python
Tensorflow 同时载入多个模型的实例讲解
2018/07/27 Python
python对视频画框标记后保存的方法
2018/12/07 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
Html5实现如何在两个div元素之间拖放图像
2013/03/29 HTML / CSS
AmazeUI的下载配置与Helloworld的实现
2020/08/19 HTML / CSS
Ralph Lauren意大利官方网站:时尚界最负盛名的品牌之一
2018/10/18 全球购物
MySQL面试题
2014/01/12 面试题
财务会计大学生自我评价
2014/04/09 职场文书
社区服务活动总结
2014/05/07 职场文书
校园安全演讲稿
2014/05/09 职场文书
教师国庆节演讲稿范文2014
2014/09/21 职场文书
公司领导班子对照检查材料
2014/09/24 职场文书
初中家长意见
2015/06/03 职场文书
《雀魂PONG☆》4月1日播出 PV角色设定情报
2022/03/20 日漫