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爬虫抓取豆瓣电影TOP100及用户头像的方法
Jan 20 Python
python使用标准库根据进程名如何获取进程的pid详解
Oct 31 Python
从头学Python之编写可执行的.py文件
Nov 28 Python
Django REST为文件属性输出完整URL的方法
Dec 18 Python
Python实现将doc转化pdf格式文档的方法
Jan 19 Python
对Python生成汉字字库文字,以及转换为文字图片的实例详解
Jan 29 Python
python for和else语句趣谈
Jul 02 Python
Python 实现黑客帝国中的字符雨的示例代码
Feb 20 Python
Python类的绑定方法和非绑定方法实例解析
Mar 04 Python
Python生成器传参数及返回值原理解析
Jul 22 Python
python的scipy.stats模块中正态分布常用函数总结
Feb 19 Python
Python基础之数据结构详解
Apr 28 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 array_map array_multisort 高效处理多维数组排序
2009/06/11 PHP
一个PHP数组应该有多大的分析
2009/07/30 PHP
PHP模板引擎Smarty内建函数详解
2016/04/11 PHP
thinkphp 抓取网站的内容并且保存到本地的实例详解
2017/08/25 PHP
PHP与以太坊交互详解
2018/08/24 PHP
短信提示使用 特效
2007/01/19 Javascript
jquery下为Event handler传递动态参数的代码
2011/01/06 Javascript
setTimeout和setInterval的区别你真的了解吗?
2011/03/31 Javascript
基于jquery实现图片广告轮换效果代码
2011/07/07 Javascript
jquery插件orbit.js实现图片折叠轮换特效
2015/04/14 Javascript
AngularJS基础学习笔记之简单介绍
2015/05/10 Javascript
jquery插件jquery.confirm弹出确认消息
2015/12/22 Javascript
全面了解JS中的匿名函数
2016/06/29 Javascript
jquery表单验证插件validation使用方法详解
2017/01/20 Javascript
canvas压缩图片转换成base64格式输出文件流
2017/03/09 Javascript
详解如何使用Node.js编写命令工具——以vue-cli为例
2017/06/29 Javascript
JS中Attr的用法详解
2017/10/09 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
40行代码把Vue3的响应式集成进React做状态管理
2020/05/20 Javascript
python中logging库的使用总结
2017/10/18 Python
django ajax发送post请求的两种方法
2020/01/05 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
2020/02/26 Python
python json.dumps() json.dump()的区别详解
2020/07/14 Python
美国电视购物HSN官网:HSN
2016/09/07 全球购物
英国殿堂级有机护肤品牌:Rodial
2017/04/17 全球购物
法国大使拉杆箱官网:DELSEY Paris
2018/03/20 全球购物
Ray-Ban雷朋太阳眼镜英国官网:Ray-Ban UK
2019/11/23 全球购物
c语言常见笔试题总结
2016/09/05 面试题
护理专业推荐信
2013/11/07 职场文书
自荐书模板
2013/12/15 职场文书
区域销售经理职责
2013/12/22 职场文书
运动会入场词50字
2014/02/20 职场文书
感恩节寄语2015
2015/03/24 职场文书
中小学教师继续教育心得体会
2016/01/19 职场文书
《猴王出世》教学反思
2016/02/23 职场文书
Opencv实现二维直方图的计算及绘制
2021/07/21 Python