基于python的Linux系統(tǒng)指定進(jìn)程性能監(jiān)控思路詳解
監(jiān)控Linux服務(wù)器的工具、組件和程序網(wǎng)上有很多,但是一臺(tái)服務(wù)器上會(huì)有很多進(jìn)程同時(shí)運(yùn)行,特別是做性能測(cè)試的時(shí)候,可能一臺(tái)服務(wù)器上部署多個(gè)服務(wù),如果只監(jiān)控整個(gè)服務(wù)器的CPU和內(nèi)存,當(dāng)某個(gè)服務(wù)出現(xiàn)性能問題時(shí),并不能有效準(zhǔn)確的定位出(當(dāng)然通過其他工具也可以實(shí)現(xiàn)),因此,很有必要只監(jiān)控指定的進(jìn)程。需求明確了,于是動(dòng)手?jǐn)]了一個(gè)性能監(jiān)控腳本。
一、整體思路
1、為了方便的啟動(dòng)監(jiān)控和停止監(jiān)控,在想查看監(jiān)控結(jié)果的時(shí)候隨時(shí)查看監(jiān)控結(jié)果,用flask開啟了一個(gè)服務(wù),通過發(fā)送get請(qǐng)求可以隨時(shí)啟停監(jiān)控和查看監(jiān)控結(jié)果。
2、針對(duì)控制是否監(jiān)控cpu、內(nèi)存、IO,開啟多線程監(jiān)控。
3、為了減少對(duì)其他組件的依賴,將監(jiān)控結(jié)果寫到日志中。
4、為了方便查看監(jiān)控結(jié)果,直接將結(jié)果以html方式返回。
二、配置文件
config.py
IP = '127.0.0.1' PORT = '5555' LEVEL = 'INFO' # log level BACKUP_COUNT = 9 # log backup counter LOG_PATH = 'logs' # log path INTERVAL = 1 # interval, run command interval. SLEEPTIME = 3 # interval, when stopping monitor, polling to start monitor when satisfying condition. ERROR_TIMES = 5 # times, number of running command. When equal, automatically stopped monitor. IS_JVM_ALERT = True # Whether to alert when the frequency of Full GC is too high. IS_MONITOR_SYSTEM = True # Whether to monitor system's CPU and Memory. IS_MEM_ALERT = True # Whether to alert when memory is too low. Alert by sending email. MIN_MEM = 2 # Minxium memory, uint: G # 0: don't clear cache, 1: clear page caches, 2: clear dentries and inodes caches, 3: include 1 and 2; # echo 1 >/proc/sys/vm/drop_caches ECHO = 0 SMTP_SERVER = 'smtp.sina.com' # SMTP server SENDER_NAME = '張三' # sender name SENDER_EMAIL = 'zhangsan@qq.com' # sender's email PASSWORD = 'UjBWYVJFZE9RbFpIV1QwOVBUMDlQUT09' # email password, base64 encode. RECEIVER_NAME = 'baidu_all' # receiver name RECEIVER_EMAIL = ['zhangsan@qq.com', 'zhangsi@qq.com'] # receiver's email DISK = 'device1' # Which disk your application runs START_TIME = 'startTime.txt' # Store the time of start monitoring. FGC_TIMES = 'FullGC.txt' # Store the time of every FullGC time. # html HTML = '<html><body>{}</body><html>' ERROR = '<p style="color:red">{}</p>' HEADER = '<div id="header"><h2 align="center">Performance Monitor (pid={})</h2></div>' ANALYSIS = '<div id="container" style="width:730px; margin:0 auto">{}</div>'
IP和PORT:開啟服務(wù)的服務(wù)器IP和端口,必須和所監(jiān)控的服務(wù)在同一臺(tái)服務(wù)器上;
BACKUP_COUNT:默認(rèn)為9,即只保留最近9天監(jiān)控結(jié)果;
INTERVAL:兩次監(jiān)控的時(shí)間間隔,默認(rèn)為1s,主要用于cpu和內(nèi)存監(jiān)控,當(dāng)同時(shí)監(jiān)控多個(gè)端口或進(jìn)程時(shí),請(qǐng)將該值設(shè)小一點(diǎn);
ERROR_TIMES:命令執(zhí)行失敗次數(shù),當(dāng)大于該次數(shù)時(shí),則會(huì)自動(dòng)停止監(jiān)控;主要用于監(jiān)控指定的進(jìn)程,如果進(jìn)程被殺掉,則必須自動(dòng)停止監(jiān)控,且必須手動(dòng)觸發(fā)再次開始監(jiān)控;如果監(jiān)控指定的端口,當(dāng)端口的進(jìn)程被殺掉后,也會(huì)停止監(jiān)控,如果端口被重新啟動(dòng),則自動(dòng)開始監(jiān)控;
IS_JVM_ALERT:僅針對(duì)java應(yīng)用,如果頻繁FullGC,則郵件提醒;一般性能測(cè)試,F(xiàn)ullGC的頻率不得小于3600秒;
IS_MONITOR_SYSTEM :是否監(jiān)控系統(tǒng)總CPU使用率和剩余內(nèi)存;
IS_MEM_ALERT:當(dāng)系統(tǒng)剩余內(nèi)存過低時(shí),是否郵件提醒;
MIN_MEM:允許系統(tǒng)最小剩余內(nèi)存,單位為G;
ECHO:當(dāng)系統(tǒng)剩余內(nèi)存過低時(shí),是否釋放緩存;0為不釋放,1為釋放頁(yè)面緩存,2為釋放dentries和inodes緩存,3為釋放1和2;
DISK:磁盤號(hào),如果監(jiān)控IO,需要輸入磁盤號(hào),通過df -h 文件名查看當(dāng)前文件掛在哪個(gè)磁盤下;
START_TIME:記錄每次手動(dòng)觸發(fā)開始監(jiān)控的時(shí)間;
FGC_TIMES:記錄每次FullGC的時(shí)間,用于排查問題;
三、接口和服務(wù)
server.py
server = Flask(__name__) permon = PerMon() # 開啟多線程 t = [threading.Thread(target=permon.write_cpu_mem, args=()), threading.Thread(target=permon.write_io, args=())] for i in range(len(t)): t[i].start() # 開始監(jiān)控 # http://127.0.0.1:5555/runMonitor?isRun=1&type=pid&num=23121&totalTime=3600 @server.route('/runMonitor', methods=['get']) def runMonitor():...... # 畫監(jiān)控結(jié)果圖 # http://127.0.0.1:5555/plotMonitor?type=pid&num=23121 @server.route('/plotMonitor', methods=['get']) def plotMonitor():....... server.run(port=cfg.PORT, debug=True, host=cfg.IP) # 開啟服務(wù)
通過在瀏覽器地址欄輸入對(duì)應(yīng)的url,即可啟停監(jiān)控和查看監(jiān)控結(jié)果
url傳參:
1、開始監(jiān)控
http://127.0.0.1:5555/runMonitor?isRun=1&type=pid&num=23121&totalTime=3600
isRun:1為開始監(jiān)控,0為停止監(jiān)控;
type和num:type=pid時(shí),表明num為進(jìn)程號(hào),type=port,表明num為端口號(hào);可以同時(shí)監(jiān)控多個(gè)端口或進(jìn)程,多個(gè)端口或進(jìn)程用英文逗號(hào)隔開;
totalTime:為監(jiān)控總時(shí)間,單位為秒;如果不傳入totalTime,則默認(rèn)一直監(jiān)控;
2、查看監(jiān)控結(jié)果
http://127.0.0.1:
5555/plotMonitor?type=port&num=23121&system=1&startTime=2019-08-03 08:08:08&duration=3600
type和num:type=pid時(shí),表明num為進(jìn)程號(hào),type=port,表明num為端口號(hào);
system:表示查看系統(tǒng)監(jiān)控結(jié)果;如果傳了type和num,不管sysytem是否傳值,都只能看到進(jìn)程的監(jiān)控結(jié)果;不傳type和num,只傳system,則可以查看系統(tǒng)監(jiān)控結(jié)果;
startTime:查看監(jiān)控結(jié)果開始時(shí)間;
duration:查看監(jiān)控結(jié)果的時(shí)長(zhǎng),單位為秒;
如果不傳startTime和duration,則默認(rèn)查看最近一次開始監(jiān)控以來的所有結(jié)果;如果需要查看某一段時(shí)間內(nèi)的監(jiān)控結(jié)果,則需要傳startTime和duration,查看監(jiān)控結(jié)果的時(shí)間范圍為從startTime開始到startTime+duration為止。
注:如果在查看監(jiān)控結(jié)果輸入的一段時(shí)間內(nèi),服務(wù)被重啟過,則進(jìn)程號(hào)會(huì)有變化,此時(shí)仍輸入重啟前的進(jìn)程號(hào),則只能查看對(duì)應(yīng)進(jìn)程號(hào)在對(duì)應(yīng)時(shí)間段內(nèi)的監(jiān)控結(jié)果。一般情況下,端口號(hào)不會(huì)輕易變化,建議查看監(jiān)控結(jié)果時(shí)輸入端口號(hào)。
四、監(jiān)控
performance_monitor.py
使用top命令監(jiān)控CPU和內(nèi)存,使用jstat命令監(jiān)控JVM內(nèi)存(僅java應(yīng)用),使用iotop命令監(jiān)控進(jìn)程讀寫磁盤,使用iostat命令監(jiān)控磁盤IO,使用netstat命令根據(jù)端口查進(jìn)程,使用ps命令查看服務(wù)啟動(dòng)時(shí)長(zhǎng)。因此,服務(wù)器必須支持以上命令,如不支持,請(qǐng)安裝。
注:由于進(jìn)程可以開啟多個(gè)線程,在查看進(jìn)程的IO時(shí),是看不到任何IO;而查看進(jìn)程開啟的某個(gè)線程IO時(shí),是可以看到IO的,但是線程是一直是在變化的;故目前暫不支持監(jiān)控指定進(jìn)程IO的。
五、查看監(jiān)控結(jié)果
draw_performance.py
1、分別畫CPU圖、內(nèi)存和JVM圖、IO圖和句柄數(shù)圖;
2、為方便統(tǒng)計(jì)CPU和IO使用情況,計(jì)算百分位數(shù);
3、為方便統(tǒng)計(jì)垃圾回收信息,計(jì)算java應(yīng)用的ygc、fgc,以及各自的頻率。
監(jiān)控結(jié)果效果圖如下:
六、擴(kuò)展函數(shù)
extern.py 有兩個(gè)功能
1、端口轉(zhuǎn)進(jìn)程
try: result = os.popen(f'netstat -nlp|grep {port} |tr -s " "').readlines() res = [line.strip() for line in result if str(port) in line] p = res[0].split(' ') pp = p[3].split(':')[-1] if str(port) == pp: pid = p[-1].split('/')[0] except Exception as err: logger.logger.error(err)
2、查找包含監(jiān)控結(jié)果的日志
整體思路:
(1)根據(jù)輸入的開始時(shí)間和結(jié)束時(shí)間,查找包含這段時(shí)間的所有日志文件;
(2)根據(jù)查找出來的日志文件,找出包含監(jiān)控結(jié)果的所有日志;
(3)畫圖的時(shí)候遍歷找出的所有日志。
補(bǔ)充
1、為了方便查看最近一次開始監(jiān)控的時(shí)間,會(huì)將每一次開始監(jiān)控的時(shí)間寫到startTime.txt文件中;
2、為了方便排查java應(yīng)用可能出現(xiàn)的問題,將每一次Full GC的時(shí)間寫到FullGC.txt文件中。
項(xiàng)目地址:https://github.com/leeyoshinari/performance_monitor
總結(jié)
以上所述是小編給大家介紹的基于python的Linux系統(tǒng)指定進(jìn)程性能監(jiān)控,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
windows安裝openssh并通過生成SSH密鑰登錄Linux服務(wù)器
本文為大家詳細(xì)講解了在windows系統(tǒng)下安裝openssh并通過生成SSH密鑰登錄Linux服務(wù)器2018-10-10apache documentroot指向htcdoc之外提示403錯(cuò)誤的解決方法
在windows和RH都碰到過,只要把主目錄指到其他地方后就出現(xiàn)權(quán)限不夠的403提示,郁悶了好久。2010-04-04Linux VPS及服務(wù)器更加安全之設(shè)置Putty SSH使用密鑰登錄
這篇文章主要介紹了Linux VPS及服務(wù)器更加安全之設(shè)置Putty SSH使用密鑰登錄,需要的朋友可以參考下2016-10-10如何在Linux操作系統(tǒng)下安裝Apache服務(wù)的方法實(shí)例詳解
這篇文章主要介紹了如何在Linux操作系統(tǒng)下安裝Apache服務(wù)的方法,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07阿里云OSS訪問權(quán)限配置(RAM權(quán)限控制)實(shí)現(xiàn)
這篇文章主要介紹了阿里云OSS訪問權(quán)限配置(RAM權(quán)限控制)實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08LuManager圖文安裝使用教程和創(chuàng)建MysqL快速建站基本教程
這篇文章主要介紹了LuManager圖文安裝使用教程和創(chuàng)建MysqL快速建站基本教程,需要的朋友可以參考下2016-04-04