-
#!/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()