#!/usr/bin/env python
# coding:utf-8
 
import sys,time
 
class DisplayFormat(object):
 
    def format_size(self,size):
        KB = 1024                   # KB -> B  1024
        MB = 1048576                # MB -> B  1024 * 1024
        GB = 1073741824             # GB -> B  1024 * 1024 * 1024
        TB = 1099511627776          # TB -> B  1024 * 1024 * 1024
 
        if size >= TB:
            size = str(size >> 40) + 'T'
        elif size < KB:
            size = str(size) + 'B'
        elif size >= GB and size < TB:
            size = str(size >> 30) + 'G'
        elif size >= MB and size < GB:
            size = str(size >> 20) + 'M'
        else:
            size = str(size >> 10) + 'K'
 
        return size
 
    formatstring = '%-18s %-10s %-12s %8s %10s %10s %10s %10s %10s %10s %10s'
 
    def echo_line(self):
        '''输出头部横线'''
        print self.formatstring % ('-'*15,'-'*10,'-'*12,'-'*12,'-'*10,'-'*10,'-'*10,'-'*10,'-'*10,'-'*10,'-'*10,)
 
    def echo_head(self):
        '''输出头部信息'''
        print self.formatstring % ('IP','Traffic','Time','Time%',200,404,403,503,500,302,304)
 
    def echo_error(self):
        '''输出错误信息'''
        print 'Usage: ' + sys.argv[0] + 'filepath [number]'
 
    def echo_time(self):
        '''输出脚本执行时间'''
        print 'The script is running %s second' % time.clock()
 
 
class HostInfo(object):
 
    # 定义一个主机ip 的所有状态列表
    host_info = ['200','404','403','503','500','302','304','size','time']
 
    def __init__(self,host):
        '''初始化一个主机信息字典'''
        self.host = host = {}.fromkeys(self.host_info,0)
 
    def add_1(self,status_size,is_size):
        '''对访问次数,http返回的状态码,ip流量进行加1操作'''
        if status_size == 'time':
            self.host['time'] += 1
        elif is_size:
            self.host['size'] = self.host['size'] + status_size
        else:
            self.host[status_size] += 1
 
    def get_value(self,value):
        '''取出字典的值'''
        return self.host[value]
 
 
class AnalysisFile(object):
 
    def __init__(self):
        '''初始化一个空字典'''
        self.empty = {}
        self.total_request_time,self.total_traffic,self.total_200,\
        self.total_404,self.total_403,self.total_503,self.total_500,\
        self.total_302,self.total_304 = 0,0,0,0,0,0,0,0,0
 
    def split_line_todict(self,line):
        '''传入文件的每一行取出0、8、9字段 生成字典 并返回这个字典'''
        line_split = line.split()
        line_dict = {'remote_host':line_split[0],'status':line_split[8],'bytes_sent':line_split[9]}
        return line_dict
 
    def read_log(self,logs):
        for line in logs:
            try:
                dict_line = self.split_line_todict(line)
                host = dict_line['remote_host']
                status = dict_line['status']
            except ValueError:
                continue
            except IndexError:
                continue
 
            if host not in self.empty:
                host_info_obj = HostInfo(host)
                self.empty[host] = host_info_obj
            else:
                host_info_obj = self.empty[host]
 
            host_info_obj.add_1('time',False)
 
            if status in host_info_obj.host_info:
                host_info_obj.add_1(status,False)
 
            try:
                bytes_sent = int(dict_line['bytes_sent'])
            except ValueError:
                bytes_sent = 0
 
            host_info_obj.add_1(bytes_sent,True)
 
        return self.empty
 
    def return_sorted_list(self,true_dict):
        '''循环读取字典,计算总的流量、总的访问次数以及总的http返回码'''
        for host_key in true_dict:
            host_value = true_dict[host_key]
            time = host_value.get_value('time')
            self.total_request_time = self.total_request_time + time
            size = host_value.get_value('size')
            self.total_traffic = self.total_traffic + size
 
            # 获取http返回状态码的次数
            v_200 = host_value.get_value('200')
            v_404 = host_value.get_value('404')
            v_403 = host_value.get_value('403')
            v_503 = host_value.get_value('503')
            v_500 = host_value.get_value('500')
            v_302 = host_value.get_value('302')
            v_304 = host_value.get_value('304')
 
            # 重新规划字典
            true_dict[host_key] = {'200':v_200,'404':v_404,'403':v_403,\
                                   '503':v_503,'500':v_500,'302':v_302,\
                                   '304':v_304,'size':size,'time':time}
 
 
            # 计算http返回状态码的总量
            self.total_200 = self.total_200 + v_200
            self.total_404 = self.total_404 + v_404
            self.total_403 = self.total_403 + v_403
            self.total_503 = self.total_503 + v_503
            self.total_500 = self.total_500 + v_500
            self.total_302 = self.total_302 + v_302
            self.total_304 = self.total_304 + v_304
 
                # 对总的访问次数和访问流量进行降序排序,并生成一个有序的列表
        sorted_list = sorted(true_dict.items(),key=lambda i:(i[1]['size'],\
                                                                 i[1]['time']),reverse=True)
 
        return sorted_list
 
 
class Main(object):
 
    def main(self):
        '''主调函数'''
        # 初始化DisplayFormat类的实例
        displayformat = DisplayFormat()
 
        args = len(sys.argv)
        if args == 1:
            displayformat.echo_error()
        elif args == 2 or args == 3:
            log_file = sys.argv[1]
            try:
                files = open(log_file,'r')
                if args == 3:
                    lines = int(sys.argv[2])
                else:
                    lines = 0
            except IOError,e:
                print
                print e
                displayformat.echo_error()
            except VaueError,e:
                print
                print e
                displayformat.echo_error()
 
        else:
            displayformat.echo_error()
 
 
        #AnalysisFile类的实例化
        fileanalysis = AnalysisFile()
 
        # 调用read_log方法
        news_dict = fileanalysis.read_log(files)
 
        # 调用return_sorted_list方法
        new_list = fileanalysis.return_sorted_list(news_dict)
 
        # 计算所有ip的总量
        total_ip = len(new_list)
 
        if lines:
            new_list = new_list[0:lines]
        files.close()
 
        # 打印出总的ip数,总访问流量,总的访问次数
        print
        total_request_time = fileanalysis.total_request_time
        total_traffic = displayformat.format_size(fileanalysis.total_traffic)
        print '总IP数量: %s    总的访问流量: %s    总的请求次数: %d' % (total_ip,\
                                                                   total_traffic,\
                                                                   total_request_time)
         
        # 打印头部信息,和横线                                                                      
        print
        displayformat.echo_head()
        displayformat.echo_line()
 
        # 循环读取news_list列表取出time项目 计算time百分比 通过displayformat格式化输出主机信息
        for i in new_list:
            time = i[1]['time']
            time_percentage = (float(time) / float(fileanalysis.total_request_time)) * 100
            print displayformat.formatstring % (i[0],\
                                                displayformat.format_size(i[1]['size']),\
                                                time,str(time_percentage)[0:5],\
                                                i[1]['200'],i[1]['404'],i[1]['403'],\
                                                i[1]['503'],i[1]['500'],i[1]['302'],i[1]['304'])
 
        if not lines or total_ip == lines:
            displayformat.echo_line()
            print displayformat.formatstring % (total_ip,total_traffic,total_request_time,'100%',\
                                                fileanalysis.total_200,fileanalysis.total_404,\
                                                fileanalysis.total_403,fileanalysis.total_503,\
                                                fileanalysis.total_500,fileanalysis.total_302,\
                                                fileanalysis.total_304)
 
        # 显示执行脚本的时间
        print
        displayformat.echo_time()
 
if __name__ == '__main__':
    main = Main()
    main.main()

Python日志统计的更多相关文章

  1. Kafka实战-实时日志统计流程

    1.概述 在<Kafka实战-简单示例>一文中给大家介绍来Kafka的简单示例,演示了如何编写Kafka的代码去生产数据和消费数据,今天给大家介绍如何去整合一个完整的项目,本篇博客我打算为 ...

  2. Node.js / Python 日志

    一.Node.js 日志 1.原生 Node.js 原生方法其实很简单,就四个: // 输出到 stdout console.log() console.info() = console.log() ...

  3. python数据统计,总数,平均值等

    一般我们进行数据统计的时候要进行数据摸查,可能是摸查整体的分布情况啊.平均值,标准差,总数,各分段的人数啊.这时候用excel或者数据库统计都不方便. 我要统计的一个文件,太大了,还得分成15个文件, ...

  4. Python日志输出——logging模块

    Python日志输出——logging模块 标签: loggingpythonimportmodulelog4j 2012-03-06 00:18 31605人阅读 评论(8) 收藏 举报 分类: P ...

  5. python日志模块logging

    python日志模块logging   1. 基础用法 python提供了一个标准的日志接口,就是logging模块.日志级别有DEBUG.INFO.WARNING.ERROR.CRITICAL五种( ...

  6. 蓝桥杯c/c++省赛真题——日志统计

    标题:日志统计 [问题描述]小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是:ts id  表示在ts时刻编号id的帖子收到一个" ...

  7. 浅析python日志重复输出问题

    浅析python日志重复输出问题 问题起源: ​ 在学习了python的函数式编程后,又接触到了logging这样一个强大的日志模块.为了减少重复代码,应该不少同学和我一样便迫不及待的写了一个自己的日 ...

  8. Python代码统计工具

    目录 Python代码统计工具 声明 一. 问题提出 二. 代码实现 三. 效果验证 Python代码统计工具 标签: Python 代码统计 声明 本文将对<Python实现C代码统计工具(一 ...

  9. 日志统计 尺取法【蓝桥杯2018 C/C++ B组】

    标题:日志统计 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞" ...

随机推荐

  1. 剑指offer 面试65题

    题目65题:不用加减乘除做加法. 解法一:Python特性 # -*- coding:utf-8 -*- class Solution: def Add(self, num1, num2): # wr ...

  2. windows安装pywin32

    下载旧版 https://sourceforge.net/projects/pywin32/files/pywin32/ 下载新版 https://github.com/mhammond/pywin3 ...

  3. windows 2008 负载均衡(NLB) 问题汇总

    1. 主机不可访问 修改host文件. 将主机名与IP做相应的映射. 它们应该是使用主机名来访问对应的服务器. host文件路径: C:\Windows\System32\drivers\etc 19 ...

  4. [笔记] Access Control Lists (ACL) 学习笔记汇总

    一直不太明白Windows的ACL是怎么回事,还是静下心来看一手的MSDN吧. [翻译] Access Control Lists [翻译] How Access Check Works Modify ...

  5. Loadrunder场景设计篇——手工场景设计

    概述 通过选择需要运行的脚本,分配运行脚本的负载生成器,在脚本中分配Vuser来建立手工场景 手工场景就是自行设置虚拟用户的变化,主要是通过设计用户的添加和减少过程,来模拟真实的用户请求模型,完成负载 ...

  6. Linux用户和用户组管理 用户管理相关命令

    用户添加命令 useradd 注意: 新添加的用户如果不设定密码是不能够登录系统的 命令格式: [root@localhost ~]#useradd [选项] 用户名 选项说明: 选项 选项说明 -u ...

  7. 线性代数:Ax=b的解

    n列的矩阵A,当且仅当向量b是列空间C(A)的一个向量时,Ax=b有解. C(A)的零空间是N(A),N(A)正交补是A的行空间C(T(A)), 依据上一章的结论,任何Rn向量可以表示为r+n,其中n ...

  8. Android系统属性SystemProperties在应用层的用法【转】

    本文转载自:https://blog.csdn.net/lilidejing/article/details/53288243 如果你看到这篇文章了,说明你已经是资深程序员,会发现整个Android系 ...

  9. centos中如何寻找Nginx,Apache,PHP,mysql的配置路径

    很多小伙伴都可能会碰到安装好环境之后忘记了或者不知道怎么查看配置环境的文件路径了, 下面我就来介绍centos中nginx.apache.php.mysql配置文件路径查看方法吧. 1.判断apach ...

  10. python进阶03

    进程线程不管哪门语言都是一块可以被重视的方向,下面一起学习学习python中的进程,线程 1.进程线程区别 通俗解释:一个程序QQ的运行就是一个进程运行:QQ中打开多个页面互不影响可以同时操作的每个页 ...