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 相关文章推荐
剖析Django中模版标签的解析与参数传递
Jul 21 Python
详解Python如何获取列表(List)的中位数
Aug 12 Python
深入理解Python中的内置常量
May 20 Python
python中的迭代和可迭代对象代码示例
Dec 27 Python
快速了解Python中的装饰器
Jan 11 Python
pandas把dataframe转成Series,改变列中值的类型方法
Apr 10 Python
Python中存取文件的4种不同操作
Jul 02 Python
Python脚本修改阿里云的访问控制列表的方法
Mar 08 Python
Python 仅获取响应头, 不获取实体的实例
Aug 21 Python
利用Python校准本地时间的方法教程
Oct 31 Python
Python字符串的修改方法实例
Dec 19 Python
详解Django配置JWT认证方式
May 09 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 auth_http类库进行身份效验
2009/03/19 PHP
详解WordPress中添加友情链接的方法
2016/05/21 PHP
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
5款Javascript颜色选择器
2009/10/25 Javascript
js中Math之random,round,ceil,floor的用法总结
2013/12/26 Javascript
jquery ajax 局部刷新小案例
2014/02/08 Javascript
JavaScript支持的最大递归调用次数分析
2014/06/24 Javascript
使用plupload自定义参数实现多文件上传
2016/07/19 Javascript
浅谈JavaScript 函数参数传递到底是值传递还是引用传递
2016/08/23 Javascript
通过原生JS实现为元素添加事件的方法
2016/11/23 Javascript
Javascript中常用类型的格式化方法小结
2016/12/26 Javascript
w3c编程挑战_初级脚本算法实战篇
2017/06/23 Javascript
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
JavaScript分步实现一个出生日期的正则表达式
2018/03/22 Javascript
详解如何用VUE写一个多用模态框组件模版
2018/09/27 Javascript
微信小程序rich-text富文本用法实例分析
2019/05/20 Javascript
详解Python中with语句的用法
2015/04/15 Python
Pythont特殊语法filter,map,reduce,apply使用方法
2016/02/27 Python
Python使用email模块对邮件进行编码和解码的实例教程
2016/07/01 Python
Python Socket编程详细介绍
2017/03/23 Python
python机器人行走步数问题的解决
2018/01/29 Python
学习python中matplotlib绘图设置坐标轴刻度、文本
2018/02/07 Python
python切片的步进、添加、连接简单操作示例
2019/07/11 Python
python 插入日期数据到Oracle实例
2020/03/02 Python
Fossil美国官网:Fossil手表、手袋、珠宝及配件
2017/02/01 全球购物
英国最大线上综合鞋类商城:Office
2017/12/08 全球购物
ORLY官网:美国专业美甲一线品牌
2019/12/11 全球购物
大学旷课检讨书
2014/01/28 职场文书
3分钟英语演讲稿
2014/04/29 职场文书
推荐信模板
2014/05/09 职场文书
2014最新自愿离婚协议书范本
2014/11/19 职场文书
行政主管岗位职责
2015/02/03 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
导游词之西安骊山
2019/12/20 职场文书
关于Oracle12C默认用户名system密码不正确的解决方案
2021/10/16 Oracle
html解决浏览器记住密码输入框的问题
2023/05/07 HTML / CSS