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 Django连接MySQL数据库做增删改查
Nov 07 Python
举例讲解Python设计模式编程的代理模式与抽象工厂模式
Jan 16 Python
Python实现简单登录验证
Apr 13 Python
python基础教程之Filter使用方法
Jan 17 Python
Python实现的选择排序算法原理与用法实例分析
Nov 22 Python
python时间日期函数与利用pandas进行时间序列处理详解
Mar 13 Python
Windows下安装Django框架的方法简明教程
Mar 28 Python
基于pip install django失败时的解决方法
Jun 12 Python
windows下cx_Freeze生成Python可执行程序的详细步骤
Oct 09 Python
python简单鼠标自动点击某区域的实例
Jun 25 Python
pytorch之添加BN的实现
Jan 06 Python
Python判断字符串是否为空和null方法实例
Apr 26 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
MySQL的FIND_IN_SET函数使用方法分享
2012/03/27 PHP
php读取目录及子目录下所有文件名的方法
2014/10/20 PHP
smarty缓存用法分析
2014/12/16 PHP
php编程中echo用逗号和用点号连接的区别
2016/03/26 PHP
PHP如何将XML转成数组
2016/04/04 PHP
ThinkPHP框架结合Ajax实现用户名校验功能示例
2019/07/03 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
利用XMLHTTP传递参数在另一页面执行并刷新本页
2006/10/26 Javascript
javascript中关于执行环境的杂谈
2011/08/14 Javascript
js操作输入框中选择内容兼容IE及其他主流浏览器
2014/04/22 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
2015/07/27 Javascript
javascript表单正则应用
2017/02/04 Javascript
fullCalendar中文API官方文档
2017/02/07 Javascript
vsCode安装使用教程和插件安装方法
2020/08/24 Javascript
js 计算图片内点个数的示例代码
2019/04/04 Javascript
微信小程序仿通讯录功能
2020/04/09 Javascript
JavaScript中的this妙用实例分析
2020/05/09 Javascript
微信小程序轮播图swiper代码详解
2020/12/01 Javascript
将pandas.dataframe的数据写入到文件中的方法
2018/12/07 Python
了解不常见但是实用的Python技巧
2019/05/23 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
使用Python合成图片的实现代码(图片添加个性化文本,图片上叠加其他图片)
2020/04/30 Python
基于CSS3实现的几个小loading效果
2018/09/27 HTML / CSS
彻底弄明白CSS3的Media Queries(跨平台设计)
2010/07/27 HTML / CSS
Ralph Lauren英国官方网站:Ralph Lauren UK
2018/04/03 全球购物
Timberland法国官网:购买靴子、鞋子、衣服、夹克和配饰
2019/11/30 全球购物
得到Class的三个过程是什么
2012/08/10 面试题
护士实习鉴定范文
2013/12/22 职场文书
《云雀的心愿》教学反思
2014/02/25 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
2015年工会工作总结
2015/03/30 职场文书
家庭贫困证明
2015/06/16 职场文书
高中同学会致辞
2015/08/01 职场文书
导游词之北京明十三陵
2019/10/28 职场文书
HttpClient实现表单提交上传文件
2022/08/14 Java/Android
微软Win11 全新照片应用面向 Dev预览版推出 新版本上手体验图集
2022/09/23 数码科技