Python寫的服務(wù)監(jiān)控程序?qū)嵗?/h1>
更新時(shí)間:2015年01月31日 14:17:13 投稿:junjie
這篇文章主要介紹了Python寫的服務(wù)監(jiān)控程序?qū)嵗?本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
前言:
Redhat下安裝Python2.7
rhel6.4自帶的是2.6, 發(fā)現(xiàn)有的機(jī)器是python2.4。 到python網(wǎng)站下載源代碼,解壓到Redhat上,然后運(yùn)行下面的命令:
復(fù)制代碼 代碼如下:
# ./configure --prefix=/usr/local/python27
# make
# make install
這樣安裝之后默認(rèn)不會(huì)啟用Python2.7,需要使用/usr/local/python27/bin/python2.7調(diào)用新版本的python。
而下面的安裝方式會(huì)直接接管現(xiàn)有的python
復(fù)制代碼 代碼如下:
# ./configure
# make
# make install
開始:
服務(wù)子進(jìn)程被監(jiān)控主進(jìn)程創(chuàng)建并監(jiān)控,當(dāng)子進(jìn)程異常關(guān)閉,主進(jìn)程可以再次啟動(dòng)之。使用了python的subprocess模塊。就這個(gè)簡(jiǎn)單的代碼,居然互聯(lián)網(wǎng)上沒有現(xiàn)成可用的例子。沒辦法,我寫好了貢獻(xiàn)出來吧。
首先是主進(jìn)程代碼:service_mgr.py
復(fù)制代碼 代碼如下:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# cheungmine
# stdin、stdout和stderr分別表示子程序的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤。
#
# 可選的值有:
# subprocess.PIPE - 表示需要?jiǎng)?chuàng)建一個(gè)新的管道.
# 一個(gè)有效的文件描述符(其實(shí)是個(gè)正整數(shù))
# 一個(gè)文件對(duì)象
# None - 不會(huì)做任何重定向工作,子進(jìn)程的文件描述符會(huì)繼承父進(jìn)程的.
#
# stderr的值還可以是STDOUT, 表示子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤也輸出到標(biāo)準(zhǔn)輸出.
#
# subprocess.PIPE
# 一個(gè)可以被用于Popen的stdin、stdout和stderr 3個(gè)參數(shù)的特輸值,表示需要?jiǎng)?chuàng)建一個(gè)新的管道.
#
# subprocess.STDOUT
# 一個(gè)可以被用于Popen的stderr參數(shù)的特輸值,表示子程序的標(biāo)準(zhǔn)錯(cuò)誤匯合到標(biāo)準(zhǔn)輸出.
################################################################################
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, # 表示子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤也輸出到標(biāo)準(zhǔn)輸出
stdout=subprocess.PIPE # 表示需要?jiǎng)?chuàng)建一個(gè)新的管道
)
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"])
然后是子進(jìn)程代碼:testpipe.py
復(fù)制代碼 代碼如下:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# cheungmine
# 模擬一個(gè)woker進(jìn)程,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上運(yùn)行很簡(jiǎn)單:
復(fù)制代碼 代碼如下:
$ python service_mgr.py
Windows上以后臺(tái)進(jìn)程運(yùn)行:
復(fù)制代碼 代碼如下:
> start pythonw service_mgr.py
代碼中需要修改:
復(fù)制代碼 代碼如下:
run_forever(["python", "testpipe.py"])
您可能感興趣的文章:- Python3遠(yuǎn)程監(jiān)控程序的實(shí)現(xiàn)方法
- Python遠(yuǎn)程視頻監(jiān)控程序的實(shí)例代碼
- 用Python的Flask框架結(jié)合MySQL寫一個(gè)內(nèi)存監(jiān)控程序
- Python實(shí)現(xiàn)監(jiān)控程序執(zhí)行時(shí)間并將其寫入日志的方法
- Python監(jiān)控服務(wù)器實(shí)用工具psutil使用解析
- python psutil監(jiān)控進(jìn)程實(shí)例
- python實(shí)現(xiàn)監(jiān)控阿里云賬戶余額功能
- 使用 Supervisor 監(jiān)控 Python3 進(jìn)程方式
- python3.8 微信發(fā)送服務(wù)器監(jiān)控報(bào)警消息代碼實(shí)現(xiàn)
- 基于python3監(jiān)控服務(wù)器狀態(tài)進(jìn)行郵件報(bào)警
- 基于python監(jiān)控程序是否關(guān)閉
相關(guān)文章
-
使用python?matplotlib?contour畫等高線圖的詳細(xì)過程講解
最近學(xué)習(xí)了matplotlib中的高線圖的繪制,所以下面這篇文章主要給大家介紹了關(guān)于使用python?matplotlib?contour畫等高線圖的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下 2022-08-08
-
Django rest framework jwt的使用方法詳解
這篇文章主要介紹了Django rest framework jwt的使用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下 2019-08-08
-
在Python中進(jìn)行自動(dòng)化單元測(cè)試的教程
這篇文章主要介紹了在Python中進(jìn)行自動(dòng)化單元測(cè)試的教程,本文來自于IBM官方文檔,需要的朋友可以參考下 2015-04-04
-
Selenium獲取登錄Cookies并添加Cookies自動(dòng)登錄的方法
這篇文章主要介紹了Selenium獲取登錄Cookies并添加Cookies自動(dòng)登錄的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧 2020-12-12
最新評(píng)論
前言:
Redhat下安裝Python2.7
rhel6.4自帶的是2.6, 發(fā)現(xiàn)有的機(jī)器是python2.4。 到python網(wǎng)站下載源代碼,解壓到Redhat上,然后運(yùn)行下面的命令:
# ./configure --prefix=/usr/local/python27
# make
# make install
這樣安裝之后默認(rèn)不會(huì)啟用Python2.7,需要使用/usr/local/python27/bin/python2.7調(diào)用新版本的python。
而下面的安裝方式會(huì)直接接管現(xiàn)有的python
# ./configure
# make
# make install
開始:
服務(wù)子進(jìn)程被監(jiān)控主進(jìn)程創(chuàng)建并監(jiān)控,當(dāng)子進(jìn)程異常關(guān)閉,主進(jìn)程可以再次啟動(dòng)之。使用了python的subprocess模塊。就這個(gè)簡(jiǎn)單的代碼,居然互聯(lián)網(wǎng)上沒有現(xiàn)成可用的例子。沒辦法,我寫好了貢獻(xiàn)出來吧。
首先是主進(jìn)程代碼:service_mgr.py
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# cheungmine
# stdin、stdout和stderr分別表示子程序的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤。
#
# 可選的值有:
# subprocess.PIPE - 表示需要?jiǎng)?chuàng)建一個(gè)新的管道.
# 一個(gè)有效的文件描述符(其實(shí)是個(gè)正整數(shù))
# 一個(gè)文件對(duì)象
# None - 不會(huì)做任何重定向工作,子進(jìn)程的文件描述符會(huì)繼承父進(jìn)程的.
#
# stderr的值還可以是STDOUT, 表示子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤也輸出到標(biāo)準(zhǔn)輸出.
#
# subprocess.PIPE
# 一個(gè)可以被用于Popen的stdin、stdout和stderr 3個(gè)參數(shù)的特輸值,表示需要?jiǎng)?chuàng)建一個(gè)新的管道.
#
# subprocess.STDOUT
# 一個(gè)可以被用于Popen的stderr參數(shù)的特輸值,表示子程序的標(biāo)準(zhǔn)錯(cuò)誤匯合到標(biāo)準(zhǔn)輸出.
################################################################################
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, # 表示子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤也輸出到標(biāo)準(zhǔn)輸出
stdout=subprocess.PIPE # 表示需要?jiǎng)?chuàng)建一個(gè)新的管道
)
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"])
然后是子進(jìn)程代碼:testpipe.py
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# cheungmine
# 模擬一個(gè)woker進(jìn)程,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上運(yùn)行很簡(jiǎn)單:
$ python service_mgr.py
Windows上以后臺(tái)進(jìn)程運(yùn)行:
> start pythonw service_mgr.py
代碼中需要修改:
run_forever(["python", "testpipe.py"])
- Python3遠(yuǎn)程監(jiān)控程序的實(shí)現(xiàn)方法
- Python遠(yuǎn)程視頻監(jiān)控程序的實(shí)例代碼
- 用Python的Flask框架結(jié)合MySQL寫一個(gè)內(nèi)存監(jiān)控程序
- Python實(shí)現(xiàn)監(jiān)控程序執(zhí)行時(shí)間并將其寫入日志的方法
- Python監(jiān)控服務(wù)器實(shí)用工具psutil使用解析
- python psutil監(jiān)控進(jìn)程實(shí)例
- python實(shí)現(xiàn)監(jiān)控阿里云賬戶余額功能
- 使用 Supervisor 監(jiān)控 Python3 進(jìn)程方式
- python3.8 微信發(fā)送服務(wù)器監(jiān)控報(bào)警消息代碼實(shí)現(xiàn)
- 基于python3監(jiān)控服務(wù)器狀態(tài)進(jìn)行郵件報(bào)警
- 基于python監(jiān)控程序是否關(guān)閉
相關(guān)文章
使用python?matplotlib?contour畫等高線圖的詳細(xì)過程講解
最近學(xué)習(xí)了matplotlib中的高線圖的繪制,所以下面這篇文章主要給大家介紹了關(guān)于使用python?matplotlib?contour畫等高線圖的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08Django rest framework jwt的使用方法詳解
這篇文章主要介紹了Django rest framework jwt的使用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08在Python中進(jìn)行自動(dòng)化單元測(cè)試的教程
這篇文章主要介紹了在Python中進(jìn)行自動(dòng)化單元測(cè)試的教程,本文來自于IBM官方文檔,需要的朋友可以參考下2015-04-04Selenium獲取登錄Cookies并添加Cookies自動(dòng)登錄的方法
這篇文章主要介紹了Selenium獲取登錄Cookies并添加Cookies自動(dòng)登錄的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12