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之??碌某?? target=
Sep 12 Python
简单谈谈Python中函数的可变参数
Sep 02 Python
python3实现TCP协议的简单服务器和客户端案例(分享)
Jun 14 Python
对Pyhon实现静态变量全局变量的方法详解
Jan 11 Python
详解pandas的外部数据导入与常用方法
May 01 Python
计算机二级python学习教程(1) 教大家如何学习python
May 16 Python
pytorch在fintune时将sequential中的层输出方法,以vgg为例
Aug 20 Python
Python3常见函数range()用法详解
Dec 30 Python
使用Tensorflow实现可视化中间层和卷积层
Jan 24 Python
Keras保存模型并载入模型继续训练的实现
Feb 20 Python
利用python调用摄像头的实例分析
Jun 07 Python
一篇文章弄懂Python关键字、标识符和变量
Jul 15 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脚本的10个技巧(2)
2006/10/09 PHP
PHP和JavaScrip分别获取关联数组的键值示例代码
2013/09/16 PHP
php插入排序法实现数组排序实例
2015/02/16 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
2015/08/23 PHP
JS 页面内容搜索,类似于 Ctrl+F功能的实现代码
2007/08/13 Javascript
formvalidator验证插件中有关ajax验证问题
2013/01/04 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
JS中getYear()和getFullYear()区别分析
2014/07/04 Javascript
javascript的理解及经典案例分析
2016/05/20 Javascript
jQuery通用的全局遍历方法$.each()用法实例
2016/07/04 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
2017/03/10 Javascript
微信小程序 action-sheet 反馈上拉菜单简单实例
2017/05/11 Javascript
vue-cli 2.*中导入公共less文件的方法步骤
2018/11/22 Javascript
JS代码触发事件代码实例
2020/01/02 Javascript
vue 中的 render 函数作用详解
2020/02/28 Javascript
Vue 实现v-for循环的时候更改 class的样式名称
2020/07/17 Javascript
[48:24]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第一场 12.09
2020/12/12 DOTA
Python爬虫框架Scrapy安装使用步骤
2014/04/01 Python
按日期打印Python的Tornado框架中的日志的方法
2015/05/02 Python
Python多层装饰器用法实例分析
2018/02/09 Python
python re模块的高级用法详解
2018/06/06 Python
使用pandas read_table读取csv文件的方法
2018/07/04 Python
Python 类的魔法属性用法实例分析
2019/11/21 Python
pytorch中使用cuda扩展的实现示例
2020/02/12 Python
如何理解python面向对象编程
2020/06/01 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
特色冷饮店创业计划书
2014/01/28 职场文书
大学校园活动策划书
2014/02/04 职场文书
报纸媒体创意广告词
2014/03/17 职场文书
低碳生活倡议书
2014/04/14 职场文书
2015建军节87周年演讲稿
2015/03/19 职场文书
实习单位推荐信
2015/03/27 职场文书
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis
python numpy中multiply与*及matul 的区别说明
2021/05/26 Python
Python  lambda匿名函数和三元运算符
2022/04/19 Python