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操作xml文件示例
Apr 07 Python
详解在Python和IPython中使用Docker
Apr 28 Python
详解Python中for循环是如何工作的
Jun 30 Python
Python全排列操作实例分析
Jul 24 Python
python排序函数sort()与sorted()的区别
Sep 18 Python
在python中按照特定顺序访问字典的方法详解
Dec 14 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
Mar 20 Python
Python日志logging模块功能与用法详解
Apr 09 Python
Django表单提交后实现获取相同name的不同value值
May 14 Python
区分python中的进程与线程
Aug 13 Python
用Python实现童年贪吃蛇小游戏功能的实例代码
Dec 07 Python
再也不用花钱买漫画!Python爬取某漫画的脚本及源码
Jun 09 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
日本十大惊悚动漫
2020/03/04 日漫
thinkphp分页实现效果
2016/10/13 PHP
PHP编程实现csv文件导入mysql数据库的方法
2017/04/29 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
js+html5操作sqlite数据库的方法
2016/02/02 Javascript
javaScript中的原型解析【推荐】
2016/05/05 Javascript
JavaScript的Backbone.js框架入门学习指引
2016/05/07 Javascript
js的form表单提交url传参数(包含+等特殊字符)的两种解决方法
2016/05/25 Javascript
jQuery学习笔记之回调函数
2016/08/15 Javascript
Js操作DOM元素及获取浏览器高宽的简单方法
2016/09/08 Javascript
vue2的todolist入门小项目的详细解析
2017/05/11 Javascript
jQuery实现文字超过1行、2行或规定的行数时自动加省略号的方法
2018/03/28 jQuery
Vue中对拿到的数据进行A-Z排序的实例
2018/09/25 Javascript
Angular7.2.7路由使用初体验
2019/03/01 Javascript
详解vue项目中使用token的身份验证的简单实践
2019/03/08 Javascript
[01:06:19]DOTA2-DPC中国联赛定级赛 LBZS vs SAG BO3第二场 1月8日
2021/03/11 DOTA
python实现探测socket和web服务示例
2014/03/28 Python
python下载图片实现方法(超简单)
2017/07/21 Python
Python使用统计函数绘制简单图形实例代码
2019/05/15 Python
python Popen 获取输出,等待运行完成示例
2019/12/30 Python
Pycharm如何导入python文件及解决报错问题
2020/05/10 Python
阿迪达斯奥地利官方商城:adidas.at
2016/10/16 全球购物
C语言50道问题
2014/10/23 面试题
员工考核管理制度
2014/02/02 职场文书
绿色城市实施方案
2014/03/19 职场文书
《风娃娃》教学反思
2014/04/19 职场文书
我的梦想演讲稿1000字
2014/08/21 职场文书
践行三严三实心得体会
2014/10/13 职场文书
2014年仓库工作总结
2014/11/20 职场文书
讲文明倡议书
2015/04/29 职场文书
管理失职检讨书
2015/05/05 职场文书
反腐倡廉观后感
2015/06/08 职场文书
仙境之桥观后感
2015/06/16 职场文书
职业规划从高考志愿专业选择开始
2019/08/08 职场文书
MySQL优化之如何写出高质量sql语句
2021/05/17 MySQL