python分析apache访问日志脚本分享
admin
2023-07-31 02:17:40
0
#!/usr/bin/env python
# coding=utf-8
 
#------------------------------------------------------
# Name:     Apache 日志分析脚本
# Purpose:   此脚本只用来分析Apache的访问日志
# Version:   2.0
# Author:    LEO
# Created:   2013-4-26
# Modified:   2013-5-4
# Copyright:  (c) LEO 2013
#------------------------------------------------------
 
import sys
import time
 
#该类是用来打印格式
class displayFormat(object):
 
  def format_size(self,size):
    \'\'\'格式化流量单位\'\'\'
    KB = 1024     
    MB = 1048576    
    GB = 1073741824  
    TB = 1099511627776
    if size >= TB :
      size = str(size / TB) + \'T\'
    elif size < KB :
      size = str(size) + \'B\'
    elif size >= GB and size < TB:
      size = str(size / GB) + \'G\'
    elif size >= MB and size < GB :
      size = str(size / MB) + \'M\'
    else :
      size = str(size / KB) + \'K\'
    return size
 
  formatstring = \'%-15s %-10s %-12s %8s %10s %10s %10s %10s %10s %10s %10s\'
 
  def transverse_line(self) :
    \'\'\'输出横线\'\'\'
    print self.formatstring % (\'-\'*15,\'-\'*10,\'-\'*12,\'-\'*12,\'-\'*10,\'-\'*10,\'-\'*10,\'-\'*10,\'-\'*10,\'-\'*10,\'-\'*10)
 
  def head(self):
    \'\'\'输出头部信息\'\'\'
    print self.formatstring % (\'IP\',\'Traffic\',\'Times\',\'Times%\',\'200\',\'404\',\'500\',\'403\',\'302\',\'304\',\'503\')
 
  def error_print(self) :
    \'\'\'输出错误信息\'\'\'
    print
    print \'Usage : \' + sys.argv[0] + \' ApacheLogFilePath [Number]\'
    print
    sys.exit(1)
 
  def execut_time(self):
    \'\'\'输出脚本执行的时间\'\'\'
    print
    print \"Script Execution Time: %.3f second\" % time.clock()
    print
 
#该类是用来生成主机信息的字典
class hostInfo(object):
   
  host_info = [\'200\',\'404\',\'500\',\'302\',\'304\',\'503\',\'403\',\'times\',\'size\']
 
  def __init__(self,host):
    self.host = host = {}.fromkeys(self.host_info,0)
 
  def increment(self,status_times_size,is_size):
    \'\'\'该方法是用来给host_info中的各个值加1\'\'\'
    if status_times_size == \'times\':
      self.host[\'times\'] += 1
    elif is_size:
      self.host[\'size\'] = self.host[\'size\'] + status_times_size
    else:
      self.host[status_times_size] += 1
 
  def get_value(self,value):
    \'\'\'该方法是取到各个主机信息中对应的值\'\'\'
    return self.host[value]
 
#该类是用来分析文件
class fileAnalysis(object):
  def __init__(self):
    \'\'\'初始化一个空字典\'\'\'
    self.report_dict = {}
    self.total_request_times,self.total_traffic,self.total_200, 
    self.total_404,self.total_500,self.total_403,self.total_302, 
    self.total_304,self.total_503 = 0,0,0,0,0,0,0,0,0
 
  def split_eachline_todict(self,line):
    \'\'\'分割文件中的每一行,并返回一个字典\'\'\'
    split_line = line.split()
    split_dict = {\'remote_host\':split_line[0],\'status\':split_line[-2],\'bytes_sent\':split_line[-1],}
    return split_dict
 
  def generate_log_report(self,logfile):
    \'\'\'读取文件,分析split_eachline_todict方法生成的字典\'\'\'
    for line in logfile:
      try:
        line_dict = self.split_eachline_todict(line)
        host = line_dict[\'remote_host\']
        status = line_dict[\'status\']
      except ValueError :
        continue
      except IndexError :
        continue
 
      if host not in self.report_dict :
        host_info_obj = hostInfo(host)
        self.report_dict[host] = host_info_obj
      else :
        host_info_obj = self.report_dict[host]
 
      host_info_obj.increment(\'times\',False)  
      if status in host_info_obj.host_info : 
        host_info_obj.increment(status,False) 
      try:
        bytes_sent = int(line_dict[\'bytes_sent\']) 
      except ValueError:
        bytes_sent = 0
      host_info_obj.increment(bytes_sent,True)
    return self.report_dict
 
  def return_sorted_list(self,true_dict):
    \'\'\'计算各个状态次数、流量总量,请求的总次数,并且计算各个状态的总量 并生成一个正真的字典,方便排序\'\'\'
    for host_key in true_dict :
      host_value = true_dict[host_key]
      times = host_value.get_value(\'times\') 
      self.total_request_times = self.total_request_times + times 
      size = host_value.get_value(\'size\') 
      self.total_traffic = self.total_traffic + size 
 
      o200 = host_value.get_value(\'200\')
      o404 = host_value.get_value(\'404\')
      o500 = host_value.get_value(\'500\')
      o403 = host_value.get_value(\'403\')
      o302 = host_value.get_value(\'302\')
      o304 = host_value.get_value(\'304\')
      o503 = host_value.get_value(\'503\')
 
      true_dict[host_key] = {\'200\':o200,\'404\':o404,\'500\':o500,\'403\':o403,\'302\':o302,\'304\':o304, 
                  \'503\':o503,\'times\':times,\'size\':size}
 
      self.total_200 = self.total_200 + o200
      self.total_404 = self.total_404 + o404
      self.total_500 = self.total_500 + o500
      self.total_302 = self.total_302 + o302
      self.total_304 = self.total_304 + o304
      self.total_503 = self.total_503 + o503
 
    sorted_list = sorted(true_dict.items(),key=lambda t:(t[1][\'times\'],t[1][\'size\']),reverse=True)
    return sorted_list
 
class Main(object):
  def main(self) :
    \'\'\'主调函数\'\'\'
    display_format = displayFormat()
    arg_length = len(sys.argv)
    if arg_length == 1 :
      display_format.error_print()
    elif arg_length == 2 or arg_length == 3:
      infile_name = sys.argv[1]
      try :
        infile = open(infile_name,\'r\')
        if arg_length == 3 :
          lines = int(sys.argv[2])
        else :
          lines = 0
      except IOError,e :
        print
        print e
        display_format.error_print()
      except ValueError :
        print
        print \"Please Enter A Volid Number !!\"
        display_format.error_print()
    else :
      display_format.error_print()
 
    fileAnalysis_obj = fileAnalysis()
    not_true_dict = fileAnalysis_obj.generate_log_report(infile)
    log_report = fileAnalysis_obj.return_sorted_list(not_true_dict)
    total_ip = len(log_report)
    if lines :
      log_report = log_report[0:lines]
    infile.close()
 
    print
    total_traffic = display_format.format_size(fileAnalysis_obj.total_traffic)
    total_request_times = fileAnalysis_obj.total_request_times
    print \'Total IP: %s  Total Traffic: %s  Total Request Times: %d\' 
       % (total_ip,total_traffic,total_request_times)
    print
    display_format.head()
    display_format.transverse_line()
 
    for host in log_report :
      times = host[1][\'times\']
      times_percent = (float(times) / float(fileAnalysis_obj.total_request_times)) * 100
      print display_format.formatstring % (host[0],
                         display_format.format_size(host[1][\'size\']),
                         times,str(times_percent)[0:5],
                         host[1][\'200\'],host[1][\'404\'],
                         host[1][\'500\'],host[1][\'403\'],
                         host[1][\'302\'],host[1][\'304\'],host[1][\'503\'])
                         
    if (not lines) or total_ip == lines :
      display_format.transverse_line()
      print display_format.formatstring % (total_ip,total_traffic, 
                         total_request_times,\'100%\',
                         fileAnalysis_obj.total_200,
                         fileAnalysis_obj.total_404,
                         fileAnalysis_obj.total_500, 
                         fileAnalysis_obj.total_403,
                         fileAnalysis_obj.total_302, 
                         fileAnalysis_obj.total_304,
                         fileAnalysis_obj.total_503)
    display_format.execut_time()
 
if __name__ == \'__main__\':
  main_obj = Main()
  main_obj.main()

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...