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 open读写文件实现脚本
Sep 06 Python
python操作xml文件详细介绍
Jun 09 Python
使用Python编写简单的画图板程序的示例教程
Dec 08 Python
对matplotlib改变colorbar位置和方向的方法详解
Dec 13 Python
pycharm中使用anaconda部署python环境的方法步骤
Dec 19 Python
对python实现模板生成脚本的方法详解
Jan 30 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
Jun 25 Python
简单了解python的break、continue、pass
Jul 08 Python
讲解Python3中NumPy数组寻找特定元素下标的两种方法
Aug 04 Python
pycharm激活码2020最新分享适用pycharm2020最新版亲测可用
Nov 22 Python
Python读取图像并显示灰度图的实现
Dec 01 Python
Python还能这么玩之用Python做个小游戏的外挂
Jun 04 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中get_object_vars()方法用法实例
2015/02/08 PHP
举例详解PHP脚本的测试方法
2015/08/05 PHP
Zend Framework动作助手Json用法实例分析
2016/03/05 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
2016/10/18 PHP
JavaScript 应用类库代码
2008/06/02 Javascript
jQuery实战之仿淘宝商城左侧导航效果
2011/04/12 Javascript
js控制分页打印、打印分页示例
2014/02/08 Javascript
单元选择合并变色示例代码
2014/05/26 Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
2015/11/06 Javascript
JavaScript 定时器 SetTimeout之定时刷新窗口和关闭窗口(代码超简单)
2016/02/26 Javascript
详解node Async/Await 更好的异步编程解决方案
2018/05/10 Javascript
layui-laydate时间日历控件使用方法详解
2018/11/15 Javascript
JS判断两个数组或对象是否相同的方法示例
2019/02/28 Javascript
微信小程序基于Taro的分享图片功能实践详解
2019/07/12 Javascript
扫微信小程序码实现网站登陆实现解析
2019/08/20 Javascript
微信小程序开发(一):服务器获取数据列表渲染操作示例
2020/06/01 Javascript
Vue 组件注册全解析
2020/12/17 Vue.js
python设置windows桌面壁纸的实现代码
2013/01/28 Python
python之yield表达式学习
2014/09/02 Python
在Python的struct模块中进行数据格式转换的方法
2015/06/17 Python
Python实现快速计算词频功能示例
2018/06/25 Python
pandas按条件筛选数据的实现
2021/02/20 Python
欧洲最大的球衣网上商店:Kitbag
2017/11/11 全球购物
Urban Outfitters德国官网:美国跨国生活方式零售公司
2018/05/21 全球购物
.NET里面如何取得当前的屏幕分辨率
2012/12/06 面试题
门前三包责任书
2014/04/15 职场文书
法制宣传日活动总结
2014/04/29 职场文书
竞争上岗演讲稿范文
2014/05/12 职场文书
学校端午节活动方案
2014/08/23 职场文书
党的群众路线对照检查材料
2014/08/27 职场文书
2014迎国庆演讲稿
2014/09/19 职场文书
2016幼儿园教师年度考核评语
2015/12/01 职场文书
(开源)微信小程序+mqtt,esp8266温湿度读取
2021/04/02 Javascript
「月刊Comic Alive」2022年5月号封面公开
2022/03/21 日漫
Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换
2022/04/24 Python
Java获取字符串编码格式实现思路
2022/09/23 Java/Android