python分析nignx访问日志脚本分享
admin
2023-07-31 02:17:45
0
#!/usr/bin/env python 
# coding=utf-8 
 
#------------------------------------------------------ 
# Name:     nginx 日志分析脚本 
# Purpose:   此脚本只用来分析nginx的访问日志 
# Version:   1.0 
# Author:    LEO 
# Created:   2013-05-07 
# Modified:   2013-05-07 
# Copyright:  (c) LEO 2013 
#------------------------------------------------------ 
 
import sys 
import time 
 
#该类是用来打印格式 
class displayFormat(object): 
 
  def format_size(self,size): 
    \'\'\'\'\'格式化流量单位\'\'\' 
    KB = 1024      #KB -> B B是字节 
    MB = 1048576    #MB -> B 
    GB = 1073741824   #GB -> B 
    TB = 1099511627776 #TB -> B 
    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] + \' NginxLogFilePath [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[8], 
           \'bytes_sent\':split_line[9],} 
    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...