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 相关文章推荐
用Python的Tornado框架结合memcached页面改善博客性能
Apr 24 Python
在Python中使用sort()方法进行排序的简单教程
May 21 Python
一篇文章读懂Python赋值与拷贝
Apr 19 Python
解决python报错MemoryError的问题
Jun 26 Python
Django实现分页功能
Jul 02 Python
替换python字典中的key值方法
Jul 06 Python
tensorflow 加载部分变量的实例讲解
Jul 27 Python
python实现在图片上画特定大小角度矩形框
Oct 24 Python
简单了解python调用其他脚本方法实例
Mar 26 Python
pytorch判断是否cuda 判断变量类型方式
Jun 23 Python
python 读取.nii格式图像实例
Jul 01 Python
详解用Python把PDF转为Word方法总结
Apr 27 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
php更新修改excel中的内容实例代码
2014/02/26 PHP
php中base_convert()进制数字转换函数实例
2014/11/20 PHP
Yii使用ajax验证显示错误messagebox的解决方法
2014/12/03 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
动态调用CSS文件的JS代码
2010/07/29 Javascript
javascript控制Div层透明属性由浅变深由深变浅逐渐显示
2013/11/12 Javascript
Node.js异步I/O学习笔记
2014/11/04 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
jQuery如何使用自动触发事件trigger
2015/11/29 Javascript
Node.js pipe实现源码解析
2017/08/12 Javascript
vue移动端实现下拉刷新
2018/04/22 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
python+django快速实现文件上传
2016/10/24 Python
Python 'takes exactly 1 argument (2 given)' Python error
2016/12/13 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
Python实现对一个函数应用多个装饰器的方法示例
2018/02/09 Python
DataFrame中的object转换成float的方法
2018/04/10 Python
Python框架Flask的基本数据库操作方法分析
2018/07/13 Python
深入解析Python小白学习【操作列表】
2019/03/23 Python
python实现批量nii文件转换为png图像
2019/07/18 Python
Pandas分组与排序的实现
2019/07/23 Python
opencv python 图片读取与显示图片窗口未响应问题的解决
2020/04/24 Python
Python读写csv文件流程及异常解决
2020/10/20 Python
分享unittest单元测试框架中几种常用的用例加载方法
2020/12/02 Python
圣彼得堡鲜花配送:Semicvetic
2020/09/15 全球购物
企业治理工作自我评价
2013/09/26 职场文书
最新个人职业生涯规划书
2014/01/22 职场文书
银行见习期自我鉴定
2014/01/29 职场文书
售后服务经理岗位职责
2014/02/25 职场文书
幼儿园教师自我鉴定
2014/03/20 职场文书
秋天的怀念教学反思
2014/04/28 职场文书
食品质量与安全专业毕业生求职信
2014/08/11 职场文书
2015年车间主任工作总结
2015/05/21 职场文书
公司环境卫生管理制度
2015/08/05 职场文书
Mac环境Nginx配置和访问本地静态资源的实现
2021/03/31 Servers
Redis中key的过期删除策略和内存淘汰机制
2022/04/12 Redis