paramiko使用tail實(shí)時(shí)獲取服務(wù)器的日志輸出詳解
基本思路
現(xiàn)在有這么一個(gè)需求需要實(shí)現(xiàn)自動(dòng)化:需要實(shí)時(shí)獲取服務(wù)器cpu,gpu溫度以及傳感器信息上報(bào)情況,對高低溫環(huán)境下對于設(shè)備運(yùn)行狀態(tài)的影響進(jìn)行測試。基本思路為利用paramiko ssh到服務(wù)器上,起一個(gè)線程用tail -f命令實(shí)時(shí)獲取日志輸出,起另外一個(gè)線程用‘cat /sys/class/thermal/thermal_zone0/temp'命令定時(shí)獲取cpu,gpu溫度。
代碼
def get_report_info_perid(self, cmd, diff_time, thre_time):
# 發(fā)送要執(zhí)行的命令
pre_time_stamp = [0] * 4
self._channel.send(cmd + '\r')
# 回顯很長的命令可能執(zhí)行較久,通過循環(huán)分批次取回回顯
time_stamp_arr = []
index = [0] * 4
current_line = b''
line_counter = 0
line_feed_byte = '\n'.encode(self.encoding)
while True:
buffer = self._channel.recv(1)
if len(buffer) == 0:
logger.info('end______________')
break
current_line += buffer
if buffer == line_feed_byte:
line = current_line.decode(self.encoding)
logger.debug('shell顯示:%s'%line)
if not line.startswith(self.rq):
line_counter += 1
current_line = b''
continue
col = self.check_type(line)
time_stamp = int(time.mktime(time.strptime(' '.join([line[:8], line[9:17]]), "%Y%m%d %H:%M:%S")))
time_stamp_dec = line[18: 21] # 精確到毫秒
time_stamp = time_stamp * 1000 + int(time_stamp_dec)
logger.info('%s:%s' % (senior_name[col], time_stamp))
self.write_xl(index[col] + 1, col, time_stamp)
index[col] += 1
if pre_time_stamp[col] == 0:
pre_time_stamp[col] = time_stamp
else:
if abs((time_stamp - pre_time_stamp[col]) - diff_time[col]) > thre_time[col]:
logger.error(
'兩幀數(shù)據(jù)間隔為{}ms,時(shí)間戳分別為:({},{}),行號(hào):{}'.format(time_stamp - pre_time_stamp[col], time_stamp, pre_time_stamp[col],
index[col]))
pre_time_stamp[col] = time_stamp
line_counter += 1
current_line = b''
def get_temp_info(self, col, max_number):
index = 0
cpu_arr, gpu_arr = [], []
while True:
cpu_temp, gpu_temp = self.get_cpu_gpu_temp()
logger.info('cpu_temp:%s, gpu_temp:%s' % (cpu_temp, gpu_temp))
cpu_arr.append(cpu_temp)
gpu_arr.append(gpu_temp)
self.write_xl(index + 1, col, cpu_temp)
self.write_xl(index + 1, col + 1, cpu_temp)
time.sleep(60)
index += 1
if max_number == index:
break
return cpu_arr, gpu_arr
遇到問題
1.問題1
一開始的cmd命令為 tail -f log.txt | grep -aE “a|b”
結(jié)果出現(xiàn)一個(gè)問題,在代碼運(yùn)行幾分鐘之后,就獲取不到數(shù)據(jù)了
一開始以為是paramiko的問題,會(huì)在一定時(shí)間之后自動(dòng)關(guān)閉client,但是經(jīng)過調(diào)試之后發(fā)現(xiàn)是阻塞在_channel.recv,一直收不到服務(wù)端的數(shù)據(jù)導(dǎo)致。
經(jīng)過百度之后發(fā)現(xiàn)由于linux的緩沖機(jī)制影響導(dǎo)致tail -f 結(jié)合管道|的時(shí)候會(huì)輸出延遲
緩沖是一種有效提高IO效率的方法,把頻繁的讀寫請求積累到一定程度后再一次性的與IO設(shè)備交互操作。
IO緩沖有3種,無緩沖,行緩沖,和全緩沖。
- 無緩沖,就是不使用緩沖機(jī)制。面向字節(jié)的設(shè)備?(stderr)
- 行緩沖,緩沖,直到遇到換行符。一般用于終端設(shè)備。
- 全緩沖,緩沖,直到buffer滿。一般用于塊設(shè)備。
在終端窗口中執(zhí)行tail命令,是面向終端設(shè)備的,會(huì)使用行緩沖,所以日志中每寫入一行,立刻就會(huì)輸出。
當(dāng)使用管道時(shí),會(huì)變?yōu)槭褂萌彌_,這樣一來,就要等到日志中寫入的字節(jié)數(shù)填滿buffer后才會(huì)輸出。
解決方法:
把tail的標(biāo)準(zhǔn)輸出重定向到標(biāo)準(zhǔn)錯(cuò)誤上,并把標(biāo)準(zhǔn)錯(cuò)誤也給管道。
因?yàn)閟tderr是無緩沖的。
例如 tail -f >&2 | grep
或者直接去掉管道
2.問題2
按照問題一的結(jié)論,我去掉了命令中的管道,直接使用 tail -f log.txt命令,將過濾放到check_type函數(shù)中進(jìn)行,發(fā)現(xiàn)運(yùn)行幾分鐘之后獲取不到數(shù)據(jù)的情況并沒有解決。于是繼續(xù)定位。最后經(jīng)過一番挫折之后發(fā)現(xiàn)是使用的tail -f命令有問題
tail -f
等同于–follow=descriptor,根據(jù)文件描述符進(jìn)行追蹤,當(dāng)文件改名或被刪除,追蹤停止
tail -F
等同于–follow=name --retry,根據(jù)文件名進(jìn)行追蹤,并保持重試,即該文件被刪除或改名后,如果再次創(chuàng)建相同的文件名,會(huì)繼續(xù)追蹤
log.txt文件在程序運(yùn)行過程中被修改了文件描述符從而導(dǎo)致tail -f不繼續(xù)跟蹤。修改為tail -F后問題解決
到此這篇關(guān)于paramiko使用tail實(shí)時(shí)獲取服務(wù)器的日志輸出的文章就介紹到這了,更多相關(guān)paramiko用tail實(shí)時(shí)獲取服務(wù)器日志輸出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中sort sorted reverse reversed函數(shù)的區(qū)別說明
這篇文章主要介紹了python中sort sorted reverse reversed函數(shù)的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05
python3 實(shí)現(xiàn)一行輸入,空格隔開的示例
今天小編就為大家分享一篇python3 實(shí)現(xiàn)一行輸入,空格隔開的示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11
一文詳解如何在Python中從字符串中提取部分內(nèi)容
這篇文章主要介紹了如何在Python中從字符串中提取部分內(nèi)容的相關(guān)資料,包括使用正則表達(dá)式、Pyparsing庫、AST(抽象語法樹)、字符串操作和函數(shù)式編程,每種方法都有其適用場景和優(yōu)缺點(diǎn),需要的朋友可以參考下2025-04-04
python實(shí)現(xiàn)自動(dòng)化之文件合并
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)化文件合并,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
一文帶你搞懂Python中isinstance和type的區(qū)別
在Python中,我們經(jīng)常需要檢查一個(gè)對象的類型,Python提供了兩種方法來獲取對象的類型:isinstance和type,這兩種方法有什么區(qū)別呢,本文將詳細(xì)介紹這兩種方法的區(qū)別和使用,需要的朋友可以參考下2023-06-06
Python 過濾錯(cuò)誤log并導(dǎo)出的實(shí)例
今天小編就為大家分享一篇Python 過濾錯(cuò)誤log并導(dǎo)出的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12

