python分析nginx日誌

利用python腳本分析nginx日誌內容,默認統計ip、訪問url、狀態,可以通過修改腳本統計分析其他字段。

一、腳本運行方式

python count_log.py -f med.xxxx.com.access.log

二、腳本內容

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
1.分析日誌,每行日誌按空格切分,取出需要統計的相應字段,作爲字典的key,遍歷相加
2.使用到字典的get方法,通過定義默認值,避免miss key的錯誤
3.使用列表解析表達式
4.使用sorted函數排序列表
5.使用argparse傳入參數
6.nginx日誌格式:
log_format         access_log
    '$remote_addr - $remote_user [$time_local] $request '
    '"$status" $body_bytes_sent "$http_referer" '
    '"$http_user_agent"  "$request_time"' '"$upstream_addr"' '"$upstream_response_time"';
7.日誌內容:
222.xx.xxx.15 - - [07/Dec/2016:00:03:27 +0800] GET /app/xxx/xxx.apk HTTP/1.0 "304" 0 "-" "Mozilla/5.0 Gecko/20100115 Firefox/3.6"  "0.055""-""-"
8.腳本運行結果:
('106.xx.xx.46', '/gateway/xxx/user/mxxxxx/submitSelfTestOfSingleQuestion', '"200"', 299)
('182.1xx.xx.83', '/', '"200"', 185)
('222.xx.1xx.15', '/', '"200"', 152)
('125.xx.2xx.58', '/', '"200"', 145)
"""
import argparse


def count_log(filename, num):
    try:
        with open(filename) as f:
            dic = {}
            for l in f:
                if not l == '\n':  # 判斷空白行
                    arr = l.split(' ')
                    ip = arr[0]
                    url = arr[6]
                    status = arr[8]
                    # 字典的key是有多個元素構成的元組
                    # 字典的get方法,對取的key的值加1,第一次循環時由於字典爲空指定的key不存在返回默認值0,因此讀第一行日誌時,統計結果爲1
                    dic[(ip, url, status)] = dic.get((ip, url, status), 0) + 1
        # 從字典中取出key和value,存在列表中,由於字典的key比較特殊是有多個元素構成的元組,通過索引k[#]的方式取出key的每個元素
        dic_list = [(k[0], k[1], k[2], v) for k, v in dic.items()]
        for k in sorted(dic_list, key=lambda x: x[3], reverse=True)[:num]:
            print(k)
    except Exception as e:
        print("open file error:", e)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="傳入日誌文件")
    # 定義必須傳入日誌文件,使用格式-f filename
    parser.add_argument('-f', action='store', dest='filename', required=True)
    # 通過-n傳入數值,取出最多的幾行,默認取出前10
    parser.add_argument('-n', action='store', dest='num', type=int, required=False, default=10)
    given_args = parser.parse_args()
    filename = given_args.filename
    num = given_args.num
    count_log(filename, num)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章