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之入门(五)缩进和选择
May 27 Python
Saltstack快速入门简单汇总
Mar 01 Python
Python列表list解析操作示例【整数操作、字符操作、矩阵操作】
Jul 25 Python
Python2/3中urllib库的一些常见用法
Dec 19 Python
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
Jan 16 Python
Python基于更相减损术实现求解最大公约数的方法
Apr 04 Python
详解python实现识别手写MNIST数字集的程序
Aug 03 Python
django 实现编写控制登录和访问权限控制的中间件方法
Jan 15 Python
在python 中split()使用多符号分割的例子
Jul 15 Python
使用Tensorboard工具查看Loss损失率
Feb 15 Python
django执行原始查询sql,并返回Dict字典例子
Apr 01 Python
Python实现加密的RAR文件解压的方法(密码已知)
Sep 11 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生成随机密码方法汇总
2015/08/27 PHP
使用php完成常见的文件上传功能(推荐)
2017/01/13 PHP
php输出图像的方法实例分析
2017/02/16 PHP
Javascript 垃圾收集机制介绍理解
2013/05/14 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
利用js读取动态网站从服务器端返回的数据
2014/02/10 Javascript
jquery自动将form表单封装成json的具体实现
2014/03/17 Javascript
JS实现自动变换的菜单效果代码
2015/09/09 Javascript
jQuery实现的鼠标滑过弹出放大图片特效
2016/01/08 Javascript
js计算时间差代码【包括计算,天,时,分,秒】
2016/04/26 Javascript
超链接怎么正确调用javascript函数
2016/05/23 Javascript
实例分析nodejs模块xml2js解析xml过程中遇到的坑
2017/03/18 NodeJs
vue学习笔记之vue1.0和vue2.0的区别介绍
2017/05/17 Javascript
easyui下拉框动态级联加载的示例代码
2017/11/29 Javascript
如何为vuex实现带参数的 getter和state.commit
2019/01/04 Javascript
通过seajs实现JavaScript的模块开发及按模块加载
2019/06/06 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
对layui初始化列表的CheckBox属性详解
2019/09/13 Javascript
在node环境下parse Smarty模板的使用示例代码
2019/11/15 Javascript
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python实现通过代理服务器访问远程url的方法
2015/04/29 Python
Python利用operator模块实现对象的多级排序详解
2017/05/09 Python
Python正则表达式指南 推荐
2018/10/09 Python
Python 输出详细的异常信息(traceback)方式
2020/04/08 Python
Django如何在不停机的情况下创建索引
2020/08/02 Python
CSS3制作精致的照片墙特效
2016/06/07 HTML / CSS
Born鞋子官网:Born Shoes
2017/04/06 全球购物
俄罗斯奢侈品牌衣服、鞋子和配饰的在线商店:INTERMODA
2020/07/17 全球购物
公司接待方案
2014/03/08 职场文书
教师节演讲稿
2014/05/06 职场文书
设备收款委托书范本
2014/10/02 职场文书
个人融资协议书
2014/10/02 职场文书
2014年行政后勤工作总结
2014/12/06 职场文书
农村党支部承诺书
2015/04/30 职场文书
高中家长意见怎么写
2015/06/03 职场文书
spring boot中nativeQuery的用法
2021/07/26 Java/Android