Python檢測服務埠存活狀態並報警

来源:http://www.cnblogs.com/XuHoo/archive/2016/09/20/5888507.html
-Advertisement-
Play Games

最近發現公司的測試環境中有個Socket服務的埠總是莫名其妙Down掉,但是服務卻正常運行著,看樣子是僵死了。。。 雖然是測試環境,但是也不能這樣放著不管,於是連夜寫了一個簡單的監控腳本。因為伺服器是Windows的,所以要用到wmi模塊。邏輯如下: 1、用wmi模塊獲取系統中處於停止狀態的服務, ...


最近發現公司的測試環境中有個Socket服務的埠總是莫名其妙Down掉,但是服務卻正常運行著,看樣子是僵死了。。。

雖然是測試環境,但是也不能這樣放著不管,於是連夜寫了一個簡單的監控腳本。因為伺服器是Windows的,所以要用到wmi模塊。邏輯如下:

1、用wmi模塊獲取系統中處於停止狀態的服務,生成一個字典。

2、判斷監控的服務是否存在於字典中,如果存在說明服務已經停止,那麼將嘗試啟動服務,併發送報警郵件。

3、向本地的Socket服務埠發送一個connect,如果捕獲到異常將嘗試重啟服務,併發送報警郵件。

4、每次執行時腳本將會迴圈執行以上步驟三次,間隔10秒,以確保服務狀態正常。

在運行的時候發現了一個問題,Python使用wmi模塊來對Windows系統進行操作的時候速度格外的慢,不知道有沒有其他的代替方法,哪位如果有更好的方法可以指點一下。

 

源碼如下:

#!/usr/bin/env python

import os
import wmi
import time
import socket
import base64
import smtplib
import logging
from email.mime.text import MIMEText


def get_stop_service(designation):
    """Get stopped service name and caption,
    Filtration 'designation' service whether there is 'Stopped'.

    :return: service state
    """
    c = wmi.WMI()
    ret = dict()
    for service in c.Win32_Service():
        state, caption = service.State, service.Caption
        if state == 'Stopped':
            t = ret.get(state, [])
            t.append(caption)
            ret[state] = t
    # If 'designation' service in the 'Stopped', return status is 'down'
    if designation in ret.get('Stopped'):
        logging.error('Service [%s] is down, try to restart the service. \r\n' % designation)
        return 'down'
    return True


def monitor(sname):
    """Send the machine IP port 20000 socket request,
    If capture the abnormal returns the string 'ex'.

    :return: string 'ex'
    """
    s = socket.socket()
    s.settimeout(3)  # timeout
    host = ('127.0.0.1', 20000)
    try:  # Try connection to the host
        s.connect(host)
    except socket.error as e:
        logging.warning('[%s] service connection failed: %s \r\n' % (sname, e))
        return 'ex'
    return True


def restart_service(rstname, conn, run):
    """First check whether the service is stopped,
    if stop, start the service directly.
    The check whether the zombies,
    if a zombie, then restart the service.

    :return: flag or True
    """
    flag = False
    try:
        # From get_stop_service() to obtain the return value, the return value
        if run == 'down':
            ret = os.system('sc start "%s"' % rstname)
            if ret != 0:
                raise Exception('[Errno %s]' % ret)
            flag = True
        elif conn == 'ex':
            retStop = os.system('sc stop "%s"' % rstname)
            retSart = os.system('sc start "%s"' % rstname)
            if retSart != 0:
                raise Exception('retStop [Status code %s] '
                                'retSart [Status code %s] ' % (retStop, retSart))
            flag = True
        else:
            logging.info('[%s] service running status to normal' % rstname)
            return True
    except Exception as e:
        logging.warning('[%s] service restart failed: %s \r\n' % (rstname, e))
        return flag


def send_mail(to_list, sub, contents):
    """Send alarm mail.

    :return: flag
    """
    mail_server = 'mail.stmp.com'  # STMP Server
    mail_user = 'YouAccount'  # Mail account
    mail_pass = base64.b64decode('Password')  # The encrypted password
    mail_postfix = 'smtp.com'  # Domain name

    me = 'Monitor alarm<%s@%s>' % (mail_user, mail_postfix)
    message = MIMEText(contents, _subtype='html', _charset='utf-8')

    message['Subject'] = sub
    message['From'] = me
    message['To'] = ';'.join(to_list)

    flag = False  # To determine whether a mail sent successfully
    try:
        s = smtplib.SMTP()
        s.connect(mail_server)
        s.login(mail_user, mail_pass)
        s.sendmail(me, to_list, message.as_string())
        s.close()
        flag = True
    except Exception, e:
        logging.warning('Send mail failed, exception: [%s]. \r\n' % e)

    return flag


def main(sname):
    """Parameter type in the name of the service need to monitor,
    perform functions defined in turn, and the return value is correct.
    After the program is running, will test three times,
    each time interval to 10 seconds.

    :return: retValue
    """
    retry = 3
    count = 0
    retValue = False  # Used return to the state of the socket
    while count < retry:
        ret = monitor(sname)
        if ret != 'ex':  # If socket connection is normaol, return retValue
            retValue = ret
            return retValue
        isDown = get_stop_service(sname)
        restart_service(rstname=sname, conn=ret, run=isDown)

        host = socket.gethostname()
        address = socket.gethostbyname(host)
        mailto_list = ['[email protected]', ]  # Alarm contacts
        send_mail(mailto_list, 
                  'Alarm',
                  ' <h4>Level: <u>ERROR</u></br> Host name: %s</br>'
                  ' IP Address: %s</br>'
                  ' Service name:</h4> <h5>%s</h5>'
                  % (host, address, sname))
        count += 1
        time.sleep(10)
    else:
        logging.error('[%s] service try to restart more than three times \r\n' % sname)

    return retValue


if __name__ == '__main__':

    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(levelname)s %(message)s',
                        datefmt='%Y/%m/%d %H:%M:%S',
                        filename='D:\\logs\\Monitor.log',
                        filemode='ab')

    name = 'Service Name'
    response = main(name)
    if response:
        logging.info('The [%s] service connection is normal \r\n' % name)

以上代碼還是有可以改進的地方,將多個服務名寫到文件中,程式去讀取文件中的服務依次進行檢測。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ➠更多技術乾貨請戳:聽雲博客 基本術語定義 1.系統棧(system stack)是一個記憶體區,位於進程地址空間的末端。 2.在將數據壓棧時,棧是自頂向下增長的,該記憶體區用於函數的局部變數提供記憶體。它也支持在調用函數時傳遞參數。 3.如果調用了嵌套的過程,棧會自上而下增長,並接受新的活動記錄(act ...
  • 題意:已知有n個城市,某歌手每月進行一場演唱會,共持續c個月,可連續兩個月在同一個城市。城市間的路費已給出,且已知每個城市在第k(1<=k<=c)個月舉辦演唱會的所得利潤,求最終的最大利潤。 分析:第i個月在第j個城市舉辦演唱會,最終可得最大利潤,由此可得狀態轉移方程:dp[i][j] = max( ...
  • 1.python使用對象模型來存儲數據。構造任何類型的值都是一個對象。”儘管python被當成一種面向對象的腳本的編程語言“,但你完全能夠寫出不使用任何類和實例的腳本。 python對象都擁有三個特性:(1)身份、(2)類型、(3)值、 (1)身份:每個對象都有一個唯一的身份來標識自己。可以使用內建 ...
  • 建議65:避開基本類型數組轉換列表陷阱 我們在開發中經常會使用Arrays和Collections這兩個工具類和列表之間轉換,非常方便,但也有時候會出現一些奇怪的問題,來看如下代碼: 也許你會說,這很簡單,list變數的元素數量當然是5了。但是運行後列印出來的列表數量為1。 事實上data確實是一個 ...
  • NamedParameterJdbcTemplate類是基於JdbcTemplate類,並對它進行了封裝從而支持命名參數特性。 NamedParameterJdbcTemplate主要提供以下三類方法:execute方法、query及queryForXXX方法、update及batchUpdate方 ...
  • ...
  • 在工作中遇到的Des解密問題,第三方發來的數據需要我們進行des解密,但是解密的結果前幾位始終是亂碼。廢了半天勁,終於找到了問題所在。 下麵先介紹一下des,瞭解des的同學可以直接看下麵的解決辦法。 Des加密 DES全稱為Data EncryptionStandard,即數據加密標準。Des加密 ...
  • 有時候我們有這樣一個需求:將動態生成的內容進行編譯 比如說用戶在客戶端瀏覽器輸入一段代碼傳到伺服器,伺服器拿到這段代碼進行編譯。 動態編譯的兩種做法: (1)通過Runtime調用javac,啟動新的進程去操作它。 Runtime runtime = Runtime.getRuntime(); Pr ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...