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使用ctypes模块调用windowsapi获取系统版本示例
Apr 17 Python
Python实现控制台输入密码的方法
May 29 Python
Python基于PyGraphics包实现图片截取功能的方法
Dec 21 Python
Python实现的朴素贝叶斯分类器示例
Jan 06 Python
python学习之hook钩子的原理和使用
Oct 25 Python
Python设计模式之简单工厂模式实例详解
Jan 22 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
Sep 11 Python
python图形绘制奥运五环实例讲解
Sep 14 Python
Python上下文管理器全实例详解
Nov 12 Python
Python+opencv+pyaudio实现带声音屏幕录制
Dec 23 Python
Python Selenium XPath根据文本内容查找元素的方法
Dec 07 Python
Pygame游戏开发之太空射击实战敌人精灵篇
Aug 05 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
根德Grundig S400/S500/S700电路分析
2021/03/02 无线电
PHP实时统计中文字数和区别
2019/02/28 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
基于jQuery的试卷自动排版系统实现代码
2011/01/06 Javascript
随窗体滑动的小插件sticky源码
2013/06/21 Javascript
枚举的实现求得1-1000所有出现1的数字并计算出现1的个数
2013/09/10 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
2015/08/06 Javascript
js实现上一页下一页的效果【附代码】
2016/03/10 Javascript
基于jQuery的Web上传插件Uploadify使用示例
2016/05/19 Javascript
js oncontextmenu事件使用详解
2017/03/25 Javascript
简化vuex的状态管理方案的方法
2018/06/02 Javascript
vue项目中运用webpack动态配置打包多种环境域名的方法
2019/06/24 Javascript
微信小程序可滑动月日历组件使用详解
2019/10/21 Javascript
js根据后缀判断文件文件类型的代码
2020/05/09 Javascript
uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果
2020/12/10 Javascript
使用python装饰器验证配置文件示例
2014/02/24 Python
探究Python多进程编程下线程之间变量的共享问题
2015/05/05 Python
python&MongoDB爬取图书馆借阅记录
2016/02/05 Python
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
Python numpy.zero() 初始化矩阵实例
2019/11/27 Python
tensorflow 20:搭网络,导出模型,运行模型的实例
2020/05/26 Python
美国特价机票专家:Airfarewatchdog
2018/01/24 全球购物
欧洲最古老的鞋厂:Peter Kaiser
2019/11/05 全球购物
新西兰购物网站:TheMarket NZ
2020/09/19 全球购物
渗透攻击的测试步骤
2014/06/07 面试题
教师岗位职责
2013/11/17 职场文书
保护动物倡议书
2014/04/15 职场文书
2014年母亲节寄语
2014/05/07 职场文书
2014年学校禁毒工作总结
2014/12/23 职场文书
大学学生个人总结
2015/02/15 职场文书
公司年会主持词范文!
2019/05/07 职场文书
原来实习报告是这样写的呀!
2019/07/03 职场文书
Web前端:CSS最强总结 附详细代码
2021/03/31 HTML / CSS
pytorch实现ResNet结构的实例代码
2021/05/17 Python
JS的深浅复制详细
2021/10/16 Javascript
SQL Server使用T-SQL语句批处理
2022/05/20 SQL Server