1. 程式人生 > >Python對Windows服務進行監控

Python對Windows服務進行監控

#-*- encoding: utf-8 -*- 
import logging 
import wmi 
import os 
import time 
from ConfigParser import ConfigParser 
import smtplib  
from email.mime.text import MIMEText  
import socket
from datetime import datetime
import re
import sys
import time
import string
import psutil 
import threading
from threading import Timer   
import logging
# 建立一個logger 
logger = logging.getLogger('Monitor') 
logger.setLevel(logging.DEBUG) 
   
# 建立一個handler,用於寫入日誌檔案 
fh = logging.FileHandler('test.log') 
fh.setLevel(logging.DEBUG) 
   
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 
fh.setFormatter(formatter) 
logger.addHandler(fh) 



reload(sys) # Python2.5 初始化後會刪除 sys.setdefaultencoding 這個方法,我們需要重新載入 
sys.setdefaultencoding('utf-8') 

def send_mail(to_list,sub,content):  
    CONFIGFILE = 'config.ini' 
    config = ConfigParser() 
    config.read(CONFIGFILE) 
    mail_host=config.get('Mail','mail_host')            #使用的郵箱的smtp伺服器地址,這裡是163的smtp地址  
    mail_user=config.get('Mail','mail_user')                            #使用者名稱  
    mail_pass=config.get('Mail','mail_pass')                                #密碼  
    mail_postfix=config.get('Mail','mail_postfix')                     #郵箱的字尾,網易就是163.com  
    me=sub+"<"+mail_user+"@"+mail_postfix+">"  
    msg = MIMEText(content,_subtype='plain',_charset='utf-8')  
    msg['Subject'] = sub  
    msg['From'] = me  
    msg['To'] = ";".join(to_list)                #將收件人列表以‘;’分隔  
    try:  
        server = smtplib.SMTP()  
        server.connect(mail_host)                            #連線伺服器  
        server.login(mail_user,mail_pass)               #登入操作  
        server.sendmail(me, to_list, msg.as_string())  
        server.close()  
        return True  
    except Exception, e:  
        print str(e)
        logger.info(str(e))     
        return False  


 #讀取配置檔案中的程序名和系統路徑,這2個引數都可以在配置檔案中修改
ProList = [] 
#定義一個列表
c = wmi.WMI() 

#獲取程序所用記憶體
def countProcessMemoey(processName):
    try:
        CONFIGFILE = 'config.ini' 
        config = ConfigParser() 
        config.read(CONFIGFILE) 

        pattern = re.compile(r'([^\s]+)\s+(\d+)\s.*\s([^\s]+\sK)')
        cmd = 'tasklist /fi "imagename eq ' + processName + '"' + ' | findstr.exe ' + processName
        result = os.popen(cmd).read()
        resultList = result.split("\n")
        totalMem = 0.0
        totalCpu = 0.0

        print "*" * 80
        for srcLine in resultList:
            srcLine = "".join(srcLine.split('\n'))
            if len(srcLine) == 0:
                break
            m = pattern.search(srcLine)
            if m == None:
                continue
            #由於是檢視python程序所佔記憶體,因此通過pid將本程式過濾掉
            if str(os.getpid()) == m.group(2):
                continue
            p = psutil.Process(int(m.group(2)))
            cpu = p.cpu_percent(interval=1)    
            ori_mem = m.group(3).replace(',','')
            ori_mem = ori_mem.replace(' K','')
            ori_mem = ori_mem.replace(r'\sK','')
            memEach = string.atoi(ori_mem)
            totalMem += (memEach * 1.0 /1024)
            totalCpu += cpu
            print 'ProcessName:'+ m.group(1) + '\tPID:' + m.group(2) + '\tmemory size:%.2f'% (memEach * 1.0 /1024), 'M' + ' CPU:'+str(cpu)+'%'
        print 'ProcessName:'+ m.group(1)+' TotalMemory:'+str(totalMem)+'M'+' totalCPU:'+str(totalCpu)+'%'
        logger.info('ProcessName:'+ m.group(1)+' TotalMemory:'+str(totalMem)+'M'+' totalCPU:'+str(totalCpu)+'%')
        print "*" * 80
    
    
        if totalMem> float(config.get('MonitorProcessValue','Memory')):
            print 'Memory Exceed!'
            IP = socket.gethostbyname(socket.gethostname())
            now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            subject = IP +' ' + processName + '記憶體使用量過高!'
            content =  now + ' ' + IP +' ' + processName + '記憶體使用量過高,達到'+str(totalMem) +'M\n請儘快處理!'
            logger.info(processName +'記憶體使用量過高,達到'+str(totalMem) +'M')
            send_mail(['
[email protected]
','[email protected]'],subject, content) if totalCpu > float(config.get('MonitorProcessValue','CPU')): print 'CPU Exceed!' IP = socket.gethostbyname(socket.gethostname()) now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') subject = IP +' ' + processName + 'CPU使用率過高!' content = now + ' ' + IP +' ' + processName + 'CPU使用率過高,達到'+str(totalCpu)+'%\n請儘快處理!' logger.info(processName +'CPU使用率過高,達到'+str(totalMem) +'M') send_mail(['
[email protected]
','[email protected]'],subject, content) except Exception, e: print str(e) logger.info(str(e)) #判斷程序是否存活 def judgeIfAlive(ProgramPath,ProcessName): try: print datetime.now().strftime('%Y-%m-%d %H:%M:%S') for process in c.Win32_Process(): ProList.append(str(process.Name)) #把所有工作管理員中的程序名新增到列表 if ProcessName in ProList: countProcessMemoey(ProcessName) #判斷程序名是否在列表中,如果是True,則所監控的服務正在 執行狀態, #列印服務正常執行 print '' print ProcessName+" Server is running..." print '' logger.info(ProcessName+" Server is running...") else: #如果程序名不在列表中,即監控的服務掛了,則在log檔案下記錄日誌 #日誌檔名是以年月日為檔名 IP = socket.gethostbyname(socket.gethostname()) now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') subject = IP +' ' + ProcessName + '已停止執行!' logger.info( ProcessName + '已停止執行!') content = now + ' ' + IP +' ' + ProcessName + '已停止執行!' +'\n請儘快處理!' send_mail(['
[email protected]
','[email protected]'],subject, content) print ProcessName+' Server is not running...' #列印服務狀態 logger.info('\n'+'Server is not running,Begining to Restart Server...'+'\n'+(time.strftime('%Y-%m-%d %H:%M:%S --%A--%c', time.localtime()) +'\n')) #寫入時間和服務狀態到日誌檔案中 os.startfile(ProgramPath) #呼叫服務重啟 logger.info(ProcessName+'Restart Server Success...'+'\n'+time.strftime('%Y-%m-%d %H:%M:%S --%A--%c', time.localtime())) print ProcessName+'Restart Server Success...' print time.strftime('%Y-%m-%d %H:%M:%S --%A--%c', time.localtime()) del ProList[:] #清空列表,否則列表會不停的新增程序名,會佔用系統資源 except Exception, e: print str(e) logger.info(str(e)) def startMonitor(ProgramPathDict,ProcessNameDict) : for i in range(0,len(ProcessNameDict)): judgeIfAlive(ProgramPathDict[i],ProcessNameDict[i]) if __name__=="__main__" : CONFIGFILE = 'config.ini' config = ConfigParser() config.read(CONFIGFILE) ProgramPathDict = config.get('MonitorProgramPath','ProgramPath').split("|") ProcessNameDict = config.get('MonitorProcessName','ProcessName').split("|") while True: startMonitor(ProgramPathDict,ProcessNameDict) time.sleep(int(config.get('MonitorProcessValue','Time')))

所用配置檔案config.ini

[MonitorProgramPath] 
ProgramPath: C:\Windows\System32\services.exe|C:\Program Files (x86)\Google\Chrome\Application\chrome.exe 
[MonitorProcessName] 
ProcessName: services.exe|chrome.exe
[MonitorProcessValue]
Memory:5000.0
CPU:50.0
Time:60
[Mail] 
mail_host: smtp.163.com
mail_user: 
mail_pass: 
mail_postfix: 163.com