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实现单线程多任务非阻塞TCP服务端
Jun 13 Python
Python PyQt5实现的简易计算器功能示例
Aug 23 Python
Django中ORM表的创建和增删改查方法示例
Nov 15 Python
Python实现PS滤镜特效Marble Filter玻璃条纹扭曲效果示例
Jan 29 Python
Python爬虫实现简单的爬取有道翻译功能示例
Jul 13 Python
解决vscode python print 输出窗口中文乱码的问题
Dec 03 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
Jul 04 Python
使用python 将图片复制到系统剪贴中
Dec 13 Python
使用pyqt 实现重复打开多个相同界面
Dec 13 Python
浅谈django 重载str 方法
May 19 Python
属性与 @property 方法让你的python更高效
Sep 21 Python
Python OpenCV超详细讲解读取图像视频和网络摄像头
Apr 02 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下HTTP Response中的Chunked编码实现方法
2008/11/19 PHP
php 获取可变函数参数的函数
2009/08/26 PHP
探讨PHP使用eAccelerator的API开发详解
2013/06/09 PHP
使用PHP实现下载CSS文件中的图片
2015/12/06 PHP
PHP中函数gzuncompress无法使用的解决方法
2017/03/02 PHP
PHP预定义接口――Iterator用法示例
2020/06/05 PHP
Web层改进II-用xmlhttp 无声息提交复杂表单
2007/01/22 Javascript
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
基于JQuery的6个Tab选项卡插件
2010/09/03 Javascript
利用jQuery操作对象数组的实现代码
2011/04/27 Javascript
javascript放大镜效果的简单实现
2013/12/09 Javascript
jQuery获得document和window对象宽度和高度的方法
2015/03/25 Javascript
jQuery 移动端artEditor富文本编辑器
2016/01/11 Javascript
基于javascript实现泡泡大冒险网页版小游戏
2016/03/23 Javascript
Javascript面试经典套路reduce函数查重
2017/03/23 Javascript
微信页面弹出键盘后iframe内容变空白的解决方案
2017/09/20 Javascript
Vue.use源码学习小结
2018/06/20 Javascript
Python里隐藏的“禅”
2014/06/16 Python
Python socket C/S结构的聊天室应用实现
2014/11/30 Python
python的keyword模块用法实例分析
2015/06/30 Python
python+opencv实现的简单人脸识别代码示例
2017/11/14 Python
Python元组拆包和具名元组解析实例详解
2018/03/26 Python
Python之time模块的时间戳,时间字符串格式化与转换方法(13位时间戳)
2019/08/12 Python
Python常用数据类型之间的转换总结
2019/09/06 Python
基于Python爬取京东双十一商品价格曲线
2020/10/23 Python
html5 canvas 实现光线沿不规则路径运动
2020/04/20 HTML / CSS
Hunter Boots美国官方网站:赫特威灵顿雨靴
2018/06/16 全球购物
Linux的文件类型
2012/03/07 面试题
后勤部长岗位职责
2013/12/14 职场文书
《莫高窟》教学反思
2014/02/25 职场文书
自荐信的格式
2014/03/10 职场文书
产品质量承诺书范文
2014/03/27 职场文书
高中竞选班长演讲稿
2014/04/24 职场文书
教师节获奖感言
2015/07/31 职场文书
加薪申请书应该这样写!
2019/07/04 职场文书
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏