全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

python实时分析日志的一个小脚本分享

前言

大家都知道Web运维总要关注相关域名的实时2xx/s、4xx/s、5xx/s、响应时间、带宽等这些指标,之前的日志是五分钟一分割,简单的用awk就可以了,现在由于要推送日志到ELK,继续之前五分钟一分割会有问题,就改为一天分割一次。改成一天一分割后,显然再继续用Shell就不合适了,于是就用Python写了下。

方法如下:

脚本主要运用了文件的seek和tell函数,原理如下:

       1.加入crontab,每5分钟执行一次

       2.只分析从上次读取日志文件的结束位置到这次读取文件时的末尾位置之间的日志,出结果
可以使用zabbix_sender把结果发送到zabbix server或者直接使用zabbix agent来读取这个文件取数据,配合zabbix出图、做报警,代码如下:

#!/usr/bin/env python
#coding: utf-8

from __future__ import division
import os

LOG_FILE = '/data0/logs/nginx/xxxx-access_log'
POSITION_FILE = '/tmp/position.log'
STATUS_FILE = '/tmp/http_status'
#crontab 执行时间
CRON_TIME = 300

def get_position():
 #第一次读取日志文件,POSITION_FILE为空
 if not os.path.exists(POSITION_FILE):
  start_position = str(0)
  end_position = str(os.path.getsize(LOG_FILE))
  fh = open(POSITION_FILE,'w')
  fh.write('start_position: %s\n' % start_position)
  fh.write('end_position: %s\n' % end_position)
  fh.close()
  os._exit(1)
 else:
  fh = open(POSITION_FILE)
  se = fh.readlines()
  fh.close()
  #其他意外情况导致POSITION_FILE内容不是两行
  if len(se) != 2:
   os.remove(POSITION_FILE)
   os._exit(1)
  last_start_position,last_end_position = [item.split(':')[1].strip() for item in se]
  start_position = last_end_position
  end_position = str(os.path.getsize(LOG_FILE))
  #日志轮转导致start_position > end_position
  #print start_position,end_position
  if start_position > end_position:
   start_position = 0
  #日志停止滚动时
  elif start_position == end_position:
   os._exit(1)
  #print start_position,end_position
  fh = open(POSITION_FILE,'w')
  fh.write('start_position: %s\n' % start_position)
  fh.write('end_position: %s\n' % end_position)
  fh.close()
  return map(int,[start_position,end_position])

def write_status(content):
 fh = open(STATUS_FILE,'w')
 fh.write(content)
 fh.close()

def handle_log(start_position,end_position):
 log = open(LOG_FILE)
 log.seek(start_position,0)
 status_2xx,status_403,status_404,status_500,status_502,status_503,status_504,status_all,rt,bandwidth = 0,0,0,0,0,0,0,0,0,0
 while True:
  current_position = log.tell()
  if current_position >= end_position:
   break
  line = log.readline()
  line = line.split(' ')
  host,request_time,time_local,status,bytes_sent = line[1],line[3],line[5],line[10],line[11]
  #print host,request_time,time_local,status,bytes_sent
  status_all += 1
  try:
   rt += float(request_time.strip('s'))
   bandwidth += int(bytes_sent)
  except:
   pass
  if status == '200' or status == '206':
   status_2xx += 1
  elif status == '403':
   status_403 += 1
  elif status == '404':
   status_404 += 1
  elif status == '500':
   status_500 += 1
  elif status == '502':
   status_502 += 1
  elif status == '503':
   status_503 += 1
  elif status == '504':
   status_504 += 1
 log.close()
 #print "status_2xx: %s\nstatus_403: %s\nstatus_404: %s\nstatus_500: %s\nstatus_502: %s\nstatus_503: %s\nstatus_504: %s\nstatus_all: %s\nrt: %s\nbandwidth: %s\n" % (status_2xx/CRON_TIME,status_403/CRON_TIME,status_404/CRON_TIME,status_500/CRON_TIME,status_502/CRON_TIME,status_503/CRON_TIME,status_504/CRON_TIME,status_all/CRON_TIME,rt/status_all,bandwidth/CRON_TIME)

 write_status("status_2xx: %s\nstatus_403: %s\nstatus_404: %s\nstatus_500: %s\nstatus_502: %s\nstatus_503: %s\nstatus_504: %s\nstatus_all: %s\nrt: %s\nbandwidth: %s\n" % (status_2xx/CRON_TIME,status_403/CRON_TIME,status_404/CRON_TIME,status_500/CRON_TIME,status_502/CRON_TIME,status_503/CRON_TIME,status_504/CRON_TIME,status_all/CRON_TIME,rt/status_all,bandwidth/CRON_TIME))

if __name__ == '__main__':
 start_position,end_position = get_position()
 handle_log(start_position,end_position)

看下分析的结果:

cat /tmp/http_status
status_2xx: 17.3333333333
status_403: 0.0
status_404: 1.0
status_500: 0.0
status_502: 0.0
status_503: 0.0
status_504: 0.0
status_all: 20.0
rt: 0.0782833333333
bandwidth: 204032.0

后来发现有点问题,start_position、end_position 使用字符串比较会有问题,如下:

In [5]: '99772400' > '100227572'
Out[5]: True

In [6]: int('99772400') > int('100227572')
Out[6]: False

因此,更正为:

#日志轮转导致start_position > end_position
#print start_position,end_position
if int(start_position) > int(end_position):
 start_position = 0
#日志停止滚动时
elif int(start_position) == int(end_position):
 os._exit(1)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# python日志实时分析  # python  # 日志分析脚本  # 实时监控日志  # Python中内置的日志模块logging用法详解  # python标准日志模块logging的使用方法  # Python中使用logging模块打印log日志详解  # Python同时向控制台和文件输出日志logging的方法  # python动态监控日志内容的示例  # Python的log日志功能及设置方法  # Python中logging日志的四个等级和使用  # python程序在k8s集群中日志不显示  # 会有  # 五分钟  # 大家都  # 就不  # 执行时间  # 写了  # 可以使用  # 发送到  # 这篇文章  # 就用  # 谢谢大家  # 总要  # 两行  # 就可以  # 为空  # 运用了  # 响应时间  # 正为  # 方法如下  # 有疑问 


相关文章: c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  如何快速完成中国万网建站详细流程?  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  太原网站制作公司有哪些,网约车营运证查询官网?  如何零基础在云服务器搭建WordPress站点?  C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换  广州建站公司哪家好?十大优质服务商推荐  制作公司内部网站有哪些,内网如何建网站?  Swift中循环语句中的转移语句 break 和 continue  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  电脑免费海报制作网站推荐,招聘海报哪个网站多?  学校为何禁止电信移动建设网站?  建站之星安装需要哪些步骤及注意事项?  如何制作算命网站,怎么注册算命网站?  表情包在线制作网站免费,表情包怎么弄?  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  已有域名如何快速搭建专属网站?  广平建站公司哪家专业可靠?如何选择?  平台云上自助建站如何快速打造专业网站?  建站之星价格显示格式升级,你的预算足够吗?  定制建站流程步骤详解:一站式方案设计与开发指南  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  如何选择靠谱的建站公司加盟品牌?  网站制作免费,什么网站能看正片电影?  如何通过万网虚拟主机快速搭建网站?  建站之星导航配置指南:自助建站与SEO优化全解析  音乐网站服务器如何优化API响应速度?  内网网站制作软件,内网的网站如何发布到外网?  如何在搬瓦工VPS快速搭建网站?  如何快速搭建高效WAP手机网站吸引移动用户?  如何在橙子建站上传落地页?操作指南详解  家庭服务器如何搭建个人网站?  如何在Golang中使用encoding/gob序列化对象_存储和传输数据  ,石家庄四十八中学官网?  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  建站上市公司网站建设方案与SEO优化服务定制指南  建站主机是什么?如何选择适合的建站主机?  建站之星如何实现网站加密操作?  重庆市网站制作公司,重庆招聘网站哪个好?  简历在线制作网站免费版,如何创建个人简历?  网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?  css网站制作参考文献有哪些,易聊怎么注册?  宁波免费建站如何选择可靠模板与平台?  网站制作说明怎么写,简述网页设计的流程并说明原因?  高端网站建设与定制开发一站式解决方案 中企动力  如何基于云服务器快速搭建个人网站?  网站代码制作软件有哪些,如何生成自己网站的代码?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  ,如何利用word制作宣传手册? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。