Python分析NGINX LOG版本二

不好意思,上一版逻辑有错误,(只分析了一次就没了)

此版改正。

按同事要改,作成传参数形式,搞定。

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

###################################
# User:chengang                   #
# Email:aguncn@163.com #
# Date:2016-02-25                 #
###################################

import time
import datetime
import sys
import os
import os.path
import re
import json

class NginxLog(object):

    def __init__(self, log_file, interface_list, seek_file):
        self.log_file = log_file
        self.interface_list = interface_list
        self.seek_file = seek_file

    # 将输出编码成json格式
    def jsonFormat(self, python_data):
        json_data = json.dumps(python_data, indent=2)
        return json_data

    # 获取电脑主机名
    def hostname(self):
        sys = os.name
        if sys == 'nt':
            hostname = os.getenv('computername')
            return hostname
        elif sys == 'posix':
            host = os.popen('echo $HOSTNAME')
            try:
                hostname = host.read()
                return hostname
            finally:
                host.close()
        else:
            return 'Unkwon hostname'

    # 将读过的文件游标写入临时文件
    def writeSeek(self, seek):
        with open(self.seek_file,'w') as f:
            f.write(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))+"\n")
            f.write(str(seek)+"\n")

    # 读出新生成的日志条目
    def LogRead(self):
        # 如果第一次运行,或是删除临时文件,从头运行,否则,从上次读取之后运行
        # 0代表从头开始,1代表当前位置,2代表文件最末尾位置。
        if os.path.exists(self.seek_file):
            with open(self.seek_file) as f:
                seek_tmp = f.readlines()
            seek_old = int(seek_tmp[1].strip())
        else:
            seek_old = 0
        with open(self.log_file) as f:
            #记录当前最新文件游标
            f.seek(0,2)
            seek_now = f.tell()
            # 读取上次读完之后的日志条目
            if seek_now >= seek_old:
                f.seek(seek_old,0)
                chunk = f.read(seek_now-seek_old)
                # 也可以考虑用xreadlines来实现
                # for line in f.xreadlines():
                #    pass # do something
            # 如果文件游标倒退,说明日志文件已轮循,从头开始
            else:
                f.seek(0,0)
                chunk = f.read(seek_now)
        # 将这次的游标写入临时文件
        self.writeSeek(seek_now)
        return chunk

    def LogStatistics(self):
        #分析NGINX日志的正则表达示,如果日志格式更改,则需要相应作更改
        #我拿到的日志样本和鹏龙的不一样,所以注释了一个字段
        #field 0
        field_remote_addr = r"?P<l_remote_addr>.*"
        #field 1
        field_remote_user = r"?P<l_remote_user>-"
        #field 2
        field_time_local = r"?P<l_time_local>\[.*\]"
        #field 3
        field_request = r"?P<l_request>\"[^\"]*\""
        #field 4
        field_status = r"?P<l_status>\"[^\"]*\""
        #field 5
        field_body_bytes_sent = r"?P<l_body_bytes_sent>\d+"
        #field 6
        field_http_refere = r"?P<l_http_refere>\"[^\"]*\""
        #field 7
        field_http_user_agent = r"?P<l_http_user_agent>\"[^\"]*\""
        #field 8
        #field_http_x_fowarded_for = r"?P<l_http_x_fowarded_for>\"[^\"]*\""
        #field 8
        field_all_cookie = r"?P<l_all_cookie>\"[^\"]*\""
        #field 9
        field_gzip_ratio = r"?P<l_gzip_ratio>\"[^\"]*\""
        #field 10
        field_upstream_addr = r"?P<l_upstream_addr>.*"
        #field 11
        field_bytes_sent = r"?P<l_bytes_sent>\d+"
        #field 12
        field_request_length = r"?P<l_request_length>\d+"
        #field 13
        field_request_time = r"?P<l_request_time>.*"

        #以下为样例,方便调试

        # 正则匹配字段
        nginxlog_pattern = re.compile(r"(%s)\s-\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)\s(%s)" \
                                      %(field_remote_addr,field_remote_user,field_time_local,field_request,field_status, \
                                        field_body_bytes_sent,field_http_refere,field_http_user_agent, \
                                        field_all_cookie,field_gzip_ratio,field_upstream_addr,field_bytes_sent,field_request_length, \
                                        field_request_time),re.VERBOSE)
        #输出结果
        result_list = []
    org_list = []
    check_list = []
        # 未启用字段,作占位用
        time_ns =  datetime.datetime.now().microsecond
        #转换成符合要求的时间秒格式
        time_stamp = int(str(time.time())[0:10])
        host_name = self.hostname()
    chunk = self.LogRead()
        # 多少个URL,就要循环读取多少次,算法粗糙,后面再想办法吧,因为如果只循环一次文件读取,则在里面要循环列表,还难理顺思路
        for interface_item in self.interface_list:
        check_list.append(interface_item.lower())
            # json格式样例 {"ns":470464001,"clock":1450368176,"value":"1","key":"macs.func.exeCount_0ms_50ms[104_202]","host":"SQSZ-L3674"},
            # 构造符合要求的字典
            interface_item_dict_count = {}
            interface_item_dict_avg_request_time = {}
            interface_item_dict_2xx = {}
            interface_item_dict_4xx = {}
            interface_item_dict_5xx = {}
            interface_item_dict_count['ns']=interface_item_dict_avg_request_time['ns']=interface_item_dict_2xx['ns']=interface_item_dict_4xx['ns']=interface_item_dict_5xx['ns']=time_ns
            interface_item_dict_count['clock']=interface_item_dict_avg_request_time['clock']=interface_item_dict_2xx['clock']=interface_item_dict_4xx['clock']=interface_item_dict_5xx['clock']=time_stamp
            interface_item_dict_count['host']=interface_item_dict_avg_request_time['host']=interface_item_dict_2xx['host']=interface_item_dict_4xx['host']=interface_item_dict_5xx['host']=host_name
            interface_item_dict_count['key'] = interface_item + '_count'
            interface_item_dict_count['value'] = 0
            interface_item_dict_avg_request_time['key'] = interface_item + '_avg_request_time'
            interface_item_dict_avg_request_time['value'] = 0
            interface_item_dict_2xx['key'] = interface_item + '_2xx'
            interface_item_dict_2xx['value'] = 0
            interface_item_dict_4xx['key'] = interface_item + '_4xx'
            interface_item_dict_4xx['value'] = 0
            interface_item_dict_5xx['key'] = interface_item + '_5xx'
            interface_item_dict_5xx['value'] = 0
            hit_url_count = 0
            for line in chunk.split('\n'):
                line_matchs = nginxlog_pattern.match(line)
                if line_matchs!=None:
                    #匹配字段
                    allGroups = line_matchs.groups()
                    remote_addr = allGroups[0]
                    #切割出真正的URL
                    request_url = allGroups[3].split()[1].split('?')[0].split('/')[-1]
                    status_code = allGroups[4]
                    request_time = allGroups[13]
            # print interface_item.lower(), request_url.lower()
            if request_url.lower() not in org_list:
            org_list.append(request_url.lower())
                    # 匹配URL之后进行数据结构操作
                    if interface_item.lower() == request_url.lower():
                        hit_url_count += 1
                        interface_item_dict_count['value'] += 1
                        interface_item_dict_avg_request_time['value'] += float(request_time)
                        if status_code.strip('\"').startswith('2'):
                            interface_item_dict_2xx['value'] += 1
                        if status_code.strip('\"').startswith('4'):
                            interface_item_dict_4xx['value'] += 1
                        if status_code.strip('\"').startswith('5'):
                            interface_item_dict_5xx['value'] += 1
            # 求平均请求反应时间
            if interface_item_dict_avg_request_time['value'] != 0:
                interface_item_dict_avg_request_time['value'] = interface_item_dict_avg_request_time['value'] / hit_url_count

            #入总列表
            result_list.append(interface_item_dict_count)
            result_list.append(interface_item_dict_avg_request_time)
            result_list.append(interface_item_dict_2xx)
            result_list.append(interface_item_dict_4xx)
            result_list.append(interface_item_dict_5xx)
        return self.jsonFormat(result_list)

    def resultOutput(self):
        pass

def main():

    # 处理传参,生成日志路径及接口列表
    arg_length = len(sys.argv)
    if arg_length < 3:
    print 'args too short , at least 2(log path and interface name)'
    print 'sample: python NginxPyLog.py /fat_nginx/host.access.log getReportData getIndexData getRealTimeDatas getDayDataBigInt getBlockData getBlockDetail getRealTimeData getTrendData'
        sys.exit(0)

    #日志定位
    log_file = sys.argv[1]
    #需要收集的接口url
    interface_list = sys.argv[2:]

    # log_file  = '/applogs/fat_nginx/host.access.log'
    # interface_list 为下面的参数组合
    '''
    getReportData
    getIndexData
    getBlockData
    getBlockDetail
    getRealTimeData
    getRealTimeDatas
    getDayDataBigInt
    getTrendData
    '''

    # 临时文件游标文件
    seek_file = '/tmp/log_check_seek.tmp'

    # 传入相应参数,实例化类,获取和打印返回值
    nginx_log = NginxLog(log_file, interface_list, seek_file)
    return_json_data = nginx_log.LogStatistics()
    print return_json_data

if __name__ == "__main__":

    main()
    

 

时间: 2024-10-26 12:58:51

Python分析NGINX LOG版本二的相关文章

Python 分析Nginx访问日志并保存到MySQL数据库实例_python

使用Python 分析Nginx access 日志,根据Nginx日志格式进行分割并存入MySQL数据库.一.Nginx access日志格式如下: 复制代码 代码如下: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_f

使用python分析git log日志示例_python

用git来管理工程的开发,git log是非常有用的'历史'资料,需求就是来自这里,我们希望能对git log有一个定制性强的过滤.此段脚本就是在完成这种类型的任务.对于一个repo所有branch中的commit,脚本将会把message中存在BUG ID的一类commits给提取整理出来,并提供了额外的search_key, 用于定制过滤. 复制代码 代码如下: # -*- coding: utf-8 -*-# created by vince67 Feb.2014# nuovince@gm

Python把Nginx日志保存到MySQL数据库

Nginx access日志格式如下:  代码如下 复制代码 #使用的nginx默认日志格式$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"' Nginx access 日志内容如下:  代码如下 复制代码

一天,python搞个分析NGINX日志的脚本

准备给ZABBIX用的. 统计接口访问字次,平均响应时间,4XX,5XX次数 以后可以再改进.. #!/usr/bin/env python # coding: utf-8 ################################### # User:chengang # # Email:aguncn@163.com # # Date:2016-02-25 # ################################### import time import datetime

python 进行nginx日志分析(分析出异常刷新某API接口的IP)

发现有IP对我们API进行大量的数量采集,所以写这个脚本来获取哪些IP只访问单一接口,却不访问其它接口,一般这样的行为,是异常的. 分析前端负载nginx的日志,日志格式如下: 114.249.4.96 - - [15/Jan/2016:23:59:47 +0800] "POST /api2/realtimetrack/ HTTP/1.1" 200 48 "-" "-" "-" 222.128.172.215 - - [15/

利用awstats分析nginx日志

今天打算分析下nginx日志,要分析nginx日志,我们可以通过shell脚本和第三方软件awstats进行分析,在此我们选择的是通过第三方软件awstats进行分析. 要使用awstats分析nginx日志,我们要安装awstats,而在安装awstats之前,我们需要先来介绍下awstats是什么? 一.awstats是什么 awstats是一个免费非常简洁而且强大有个性的基于Perl语言的WEB日志分析工具. 它可以统计网站的如下信息: 1):访问量.访问次数.页面浏览量.点击数.数据流量

使用AWstats分析Nginx访问日志

软件下载地址:http://awstats.sourceforge.net/ 我下载的是稳定版本awstats-6.95.tar.gz 先上传下载文件到服务器上我习惯放在/opt下面 一.解压软件包: tar zxvf  awstats-6.95.tar.gz 然后放到/usr/local/下面 mv awstats-6.95 /usr/local/awstats 二.接着执行 tools 目录中的 awstats_configure.pl 配置向导,创建一个新的统计 [root@www too

数据-python分析apache日志,大家看看错在哪

问题描述 python分析apache日志,大家看看错在哪 import os import json import http.client import codecs LogFile='/mnt/log/meiyiren.log' #日志 logMess='/tmp/acc.log' if os.path.isfile(logMess): os.system('cp /dev/null %s'% logMess) file=codecs.open(logMess,'w+',encoding='

python分析nignx访问日志脚本分享_python

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