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实现探测socket和web服务示例
Mar 28 Python
Python实现发送email的几种常用方法
Aug 18 Python
使用Python通过win32 COM实现Word文档的写入与保存方法
May 08 Python
django反向解析和正向解析的方式
Jun 05 Python
利用pandas将numpy数组导出生成excel的实例
Jun 14 Python
Python 给某个文件名添加时间戳的方法
Oct 16 Python
Python使用dict.fromkeys()快速生成一个字典示例
Apr 24 Python
python pygame实现方向键控制小球
May 17 Python
python Pandas如何对数据集随机抽样
Jul 29 Python
Pandas —— resample()重采样和asfreq()频度转换方式
Feb 26 Python
Python实现转换图片背景颜色代码
Apr 30 Python
浅谈Python3中datetime不同时区转换介绍与踩坑
Aug 02 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实现的观察者模式实例
2017/06/21 PHP
浅析PHP类的反射来实现依赖注入过程
2018/02/06 PHP
php7 参数、整形及字符串处理机制修改实例分析
2020/05/25 PHP
Javascript 两个窗体之间传值实现代码
2009/09/25 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
2010/08/05 Javascript
Javascript实现DIV滚动自动滚动到底部的代码
2012/03/01 Javascript
到处都是jQuery选择器的年代 不了解它们的性能,行吗
2012/06/18 Javascript
基于Jquery和CSS3制作数字时钟附源码下载(CSS3篇)
2015/11/24 Javascript
jQuery实现可拖拽3D万花筒旋转特效
2017/01/03 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
Vue父组件调用子组件事件方法
2018/02/23 Javascript
通过nodejs 服务器读取HTML文件渲染到页面的方法
2018/05/17 NodeJs
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
小程序开发中如何使用async-await并封装公共异步请求的方法
2019/01/20 Javascript
[50:11]2018DOTA2亚洲邀请赛 4.7总决赛 LGD vs Mineski 第三场
2018/04/09 DOTA
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
python中self原理实例分析
2015/04/30 Python
Django框架中render_to_response()函数的使用方法
2015/07/16 Python
Python中eval带来的潜在风险代码分析
2017/12/11 Python
Python如何使用OS模块调用cmd
2020/02/27 Python
Python使用Chrome插件实现爬虫过程图解
2020/06/09 Python
Pytorch - TORCH.NN.INIT 参数初始化的操作
2021/02/27 Python
CSS3 选择器 伪类选择器介绍
2012/01/21 HTML / CSS
html5中如何将图片的绝对路径转换成文件对象
2018/01/11 HTML / CSS
莫斯科珠宝厂官方网站:Miuz
2020/09/19 全球购物
运动会入场解说词
2014/02/07 职场文书
岗位聘任书范文
2014/03/29 职场文书
护士长竞聘书
2014/03/31 职场文书
员工薪酬激励方案
2014/06/13 职场文书
岗位职责范本大全
2015/02/26 职场文书
工厂采购员岗位职责
2015/04/07 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
2015年仓库管理工作总结
2015/05/25 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python
一文简单了解MySQL前缀索引
2022/04/03 MySQL