paramiko使用tail实时获取服务器的日志输出详解


Posted in Python onDecember 06, 2020

基本思路

现在有这么一个需求需要实现自动化:需要实时获取服务器cpu,gpu温度以及传感器信息上报情况,对高低温环境下对于设备运行状态的影响进行测试。基本思路为利用paramiko ssh到服务器上,起一个线程用tail -f命令实时获取日志输出,起另外一个线程用‘cat /sys/class/thermal/thermal_zone0/temp'命令定时获取cpu,gpu温度。

代码

def get_report_info_perid(self, cmd, diff_time, thre_time):
  # 发送要执行的命令
  pre_time_stamp = [0] * 4
  self._channel.send(cmd + '\r')
  # 回显很长的命令可能执行较久,通过循环分批次取回回显
  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(
       '两帧数据间隔为{}ms,时间戳分别为:({},{}),行号:{}'.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”

结果出现一个问题,在代码运行几分钟之后,就获取不到数据了

一开始以为是paramiko的问题,会在一定时间之后自动关闭client,但是经过调试之后发现是阻塞在_channel.recv,一直收不到服务端的数据导致。

经过百度之后发现由于linux的缓冲机制影响导致tail -f 结合管道|的时候会输出延迟

缓冲是一种有效提高IO效率的方法,把频繁的读写请求积累到一定程度后再一次性的与IO设备交互操作。

IO缓冲有3种,无缓冲,行缓冲,和全缓冲。

  • 无缓冲,就是不使用缓冲机制。面向字节的设备?(stderr)
  • 行缓冲,缓冲,直到遇到换行符。一般用于终端设备。
  • 全缓冲,缓冲,直到buffer满。一般用于块设备。

在终端窗口中执行tail命令,是面向终端设备的,会使用行缓冲,所以日志中每写入一行,立刻就会输出。

当使用管道时,会变为使用全缓冲,这样一来,就要等到日志中写入的字节数填满buffer后才会输出。

解决方法:

把tail的标准输出重定向到标准错误上,并把标准错误也给管道。

因为stderr是无缓冲的。

例如 tail -f >&2 | grep

或者直接去掉管道

2.问题2

按照问题一的结论,我去掉了命令中的管道,直接使用 tail -f log.txt命令,将过滤放到check_type函数中进行,发现运行几分钟之后获取不到数据的情况并没有解决。于是继续定位。最后经过一番挫折之后发现是使用的tail -f命令有问题

tail -f

等同于?follow=descriptor,根据文件描述符进行追踪,当文件改名或被删除,追踪停止

tail -F

等同于?follow=name --retry,根据文件名进行追踪,并保持重试,即该文件被删除或改名后,如果再次创建相同的文件名,会继续追踪

log.txt文件在程序运行过程中被修改了文件描述符从而导致tail -f不继续跟踪。修改为tail -F后问题解决

到此这篇关于paramiko使用tail实时获取服务器的日志输出的文章就介绍到这了,更多相关paramiko用tail实时获取服务器日志输出内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
web.py在模板中输出美元符号的方法
Aug 26 Python
python在windows下实现ping操作并接收返回信息的方法
Mar 20 Python
使用Python设置tmpfs来加速项目的教程
Apr 17 Python
轻松实现python搭建微信公众平台
Feb 16 Python
python实现简单购物商城
May 21 Python
使用python实现快速搭建简易的FTP服务器
Sep 12 Python
Python代码使用 Pyftpdlib实现FTP服务器功能
Jul 22 Python
Python IDE Pycharm中的快捷键列表用法
Aug 08 Python
Python爬虫 urllib2的使用方法详解
Sep 23 Python
在python里使用await关键字来等另外一个协程的实例
May 04 Python
Python 处理日期时间的Arrow库使用
Aug 18 Python
python使用matplotlib绘制图片时x轴的刻度处理
Aug 30 Python
python中二分查找法的实现方法
Dec 06 #Python
python中判断数字是否为质数的实例讲解
Dec 06 #Python
Django搭建项目实战与避坑细节详解
Dec 06 #Python
python温度转换华氏温度实现代码
Dec 06 #Python
python openssl模块安装及用法
Dec 06 #Python
python help函数实例用法
Dec 06 #Python
python中复数的共轭复数知识点总结
Dec 06 #Python
You might like
thinkphp判断访客为手机端或PC端的方法
2014/11/24 PHP
smarty自定义函数用法示例
2016/05/20 PHP
详解PHP中websocket的使用方法
2016/09/15 PHP
Laravel关系模型指定条件查询方法
2019/10/10 PHP
window.onload 加载完毕的问题及解决方案(上)
2009/07/09 Javascript
利用javascript/jquery对上传文件格式过滤的方法
2009/07/25 Javascript
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
Javascript中string转date示例代码
2013/11/01 Javascript
javascript结合fileReader 实现上传图片
2015/01/30 Javascript
JS实现的论坛Ajax打分效果完整实例
2015/10/31 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
2016/09/06 Javascript
JS 循环li添加点击事件 (闭包的应用)
2016/12/10 Javascript
详解Angular 中 ngOnInit 和 constructor 使用场景
2017/06/22 Javascript
React.js绑定this的5种方法(小结)
2018/06/05 Javascript
js中事件对象和事件委托的介绍
2019/01/21 Javascript
重学 JS:为啥 await 不能用在 forEach 中详解
2019/04/15 Javascript
javascript写一个ajax自动拦截并下载数据代码实例
2019/09/07 Javascript
JavaScript相等运算符的九条规则示例详解
2019/10/20 Javascript
详解Vue template 如何支持多个根结点
2020/02/10 Javascript
在Webpack中用url-loader处理图片和字体的问题
2020/04/28 Javascript
[01:06]DOTA2亚洲邀请赛专属珍藏-荧煌之礼
2017/03/24 DOTA
跟老齐学Python之关于循环的小伎俩
2014/10/02 Python
Python实现的手机号归属地相关信息查询功能示例
2017/06/08 Python
Python使用内置json模块解析json格式数据的方法
2017/07/20 Python
Python实现的概率分布运算操作示例
2017/08/14 Python
django中send_mail功能实现详解
2018/02/06 Python
python实现简单图片物体标注工具
2019/03/18 Python
OpenCV Python实现图像指定区域裁剪
2021/03/12 Python
css 省略号 css3让多余的字符串消失并附加省略号的实现代码
2013/02/07 HTML / CSS
美国在线工具商店:Acme Tools
2018/06/26 全球购物
学习委员自我鉴定
2014/01/13 职场文书
高三励志标语
2014/06/05 职场文书
2014年教育培训工作总结
2014/12/08 职场文书
雨中的树观后感
2015/06/03 职场文书
python 实现图与图之间的间距调整subplots_adjust
2021/05/21 Python
Win11软件图标固定到任务栏
2022/04/19 数码科技